本文讲述 JavaScript 的作用域,包括局部变量和全局变量。
1.局部变量
1.1 以函数为单位
JavaScript 的局部变量是以函数为作用区间的,而非像 C/C++/Java 那样的代码块(以花括号为单位),比如:
例1:
var s = "hello";
function () {
if (true) {
var s = "world";
}
console.log.(s); // 输出 world
}
1.2 静态作用域
再来看这个例子:
例2:
var scope = 'global';
var f = function() {
console.log(scope); // 输出 undefined
var scope = 'f';
}
f();
这个例子中,执行到 console.log(scope)
时,搜索作用域即函数体,发现变量 scope
有定义,但是还没有赋值,此时为空,即 undefined。
例3:
var f = function() {
var scope = 'f0';
(function() {
var scope = 'f1';
(function() {
console.log(scope); // 输出 f1
})();
})();
};
f();
例3 涉及函数嵌套和函数的自调用。
例4:
var scope = 'top';
var f1 = function() {
console.log(scope);
};
f1(); // 输出 top
var f2 = function() {
var scope = 'f2';
f1();
};
f2(); // 输出 top
由上例可以看出,JavaScript 的作用域不是运行时确定的,而是在词法分析阶段就确定了,称为“静态作用域”或“词法作用域”。
2.全局变量
JavaScript 中的 window 对象和 Node.js 里的 global 对象都是全局变量,可以在任何地方直接使用。
满足以下条件的变量即为全局变量:
- 在最外层定义的变量;
- 全局变量的属性;
- 隐式定义的变量(即不通过
var
声明而直接赋值的变量);
其中,不推荐使用隐式定义的全局变量,特别是在 Node.js 中,这有悖模块化编程的原则。