JS中作用域
var scope = 'global';
var f = function () {
console.log(scope); // 输出 undefined
var scope = 'f';
}
f();
上面代码可能和你预想的不一样,没有输出 global, 而是undefined,这是为什么呢?
这是 JavaScript
的一个特性,按照作用域搜索顺序,在 console.log
函数访问 scope
变
量时, JavaScript
会先搜索函数 f 的作用域,恰巧在 f 作用域里面搜索到 scope
变量,
所以上层作用域中定义的 scope
就被屏蔽了,但执行到 console.log
语句时, scope
还
没被定义,或者说初始化,所以得到的就是 undefined
值了
1 var f = function() { 2 var scope = 'f0'; 3 (function() { 4 var scope = 'f1'; 5 (function() { 6 console.log(scope); // 输出 f1 7 })(); 8 })(); 9 }; 10 f();
上面是一个函数作用域嵌套的例子,我们在最内层函数引用了 scope
变量,通过作用
域搜索,找到了其父作用域中定义的 scope
变量。
有一点需要注意:函数作用域的嵌套关系是定义时决定的,而不是调用时决定的,也就
是说, JavaScript
的作用域是静态作用域,又叫词法作用域,这是因为作用域的嵌套关系可
以在语法分析时确定,而不必等到运行时确定。下面的例子说明了这一切:
var scope = 'top'; var f1 = function() { console.log(scope); }; f1(); // 输出 top var f2 = function() { var scope = 'f2'; f1(); }; f2(); // 输出 top
这个例子中,通过 f2
调用的 f1
在查找 scope
定义时,找到的是父作用域中定义
的 scope
变量,而不是 f2
中定义的 scope
变量。这说明了作用域的嵌套关系不是在调用
时确定的,而是在定义时确定的