在开始之前,我们先来看一段代码:
var name = 'window';
function display() {
alert(name);
var name = 'local';
alert(name);
}
display();
请不要去运行代码,根据你掌握的js知识来给出你的答案,我相信会有很多童鞋会说这很简单啊,不就是window和local吗?!然而事实真的是这样吗?
作用域
要理解词法作用域,首先要明白什么是作用域。作用域是变量和函数的可访问范围,控制着变量和函数的可见性及什么周期。一般来说js中的作用域可以分为全局作用域和局部作用域(es6还有块级作用域)。而JavaScript的词法作用域采用的是静态作用域
- 静态作用域:指词法作用域在词法分析阶段就已经确定了,不会改变,可以简单理解为取决于源代码。
- 动态作用域:会根据程序的调用、执行而改变,取决于在什么地方被调用。
词法作用域
一个文档流中的JavaScript代码的执行顺序大概分为以下几个步骤:
1、读入第一个代码片段(js引擎不是一行一行的分析代码,而是一段一段的分析执行)。
2、进行词法分析,检查语法是否有错误(比如是否少了括号...),如果有错误则抛出错误。
3、对var定义的变量和function关键字定义的函数进行‘预解析’,也就是我们常说“变量提升”。
4、执行代码段,如果发生错误,抛出错误异常。
5、如果还有下一段代码,则继续读入下一段代码,并且重复第2步。
6、结束。
附一张图:
我们来分析开篇的代码:
调用display函数的时候,读入代码片段,进入第二步进行词法分析,未发现错误,然后进行第三部,进行预解析,即变量提升,将变量name提升到函数的第一行,此时只有var name,并未进行赋值,因此第一个alert的值是undefined;继续执行name = ‘local’;因此第二alert的值为local。所以正确答案是undefined和local。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。