1.用var定义循环变量
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();//2
arr[1]();//2
我们看到,两次输出的i
都是2
,这是因为循环变量i
是使用var
声明的,var
声明的变量不存在块级作用域,是全局存在的,又因为程序是顺序执行的,所以function
这种复杂数据类型会存在堆里面,当for
循环执行完了函数才开始被调用,而此时,我们的循环变量i
在执行完最后一次循环后,又进行了i++
才跳出循环,即i=2
,所以此时函数打印出来的只能为2
2.用let定义循环变量
var arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();//0
arr[1]();//1
我们看到,这次输出的i
不再都是2
,这是因为循环变量i
是使用let
声明的,let
声明的变量存在块级作用域,在程序顺序执行时,function
这种复杂数据类型依然会存在堆里面,当for
循环执行完了函数才开始被调用,不同的是,我们每循环一次会产生一个块级作用域,每个块级作用域里变量i
的值是不同的,当我们的函数调用时,会在作用域链中逐层寻找i
,找到了打印输出。