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