javascript的作用域等级为function-block level。
var
var用于声明local变量,其在全局代码下不会产生作用域影响,但是var会触发变量名提升。
闭包
闭包的解释比较多,我倾向的解释为函数能够访问外围环境里的自由变量
,那么基于此定义,javascript表现的闭包特性为:变量使用的时候在当前作用域未找到声明,于是到包含本作用域的外层作用域中寻找,逐层寻找直到全局作用域。
var foo = 1; // Global
fee = 1; // Global
function test() {
var fee = 2; // Local
function func() {
console.log("foo " + foo); // foo 1
foo = 3; // Global
console.log("fee " + fee); // fee 2
fee = 3; // use Closure
}
func();
console.log("foo " + foo); // foo 3
console.log("fee " + fee); // fee 3
}
test();
console.log("foo " + foo); // foo 3
console.log("fee " + fee); // fee 1
观察例子,var fee = 2;
由于变量名提升,解析为var fee; fee = 2;
,所以此时全局作用域和test作用域各有一个fee变量。func中的foo由于没有在本作用域声明,所以会使用闭包特性,最终调用的是全局的foo变量;而func中的fee同样没有在本作用域声明,最后使用的是test作用域下的fee变量。因此foo = 3
修改的是全局的foo,而fee = 3
修改的是test作用域下的fee。
坑
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 5);
}
// 输出
// 5
// 5
// 5
// 5
// 5