var arr = [];
for(**var** i = 0; i < 10; i++){
arr[i] = function(){
return i;
};
}
for(var j = 0; j < arr.length; j++){
console.log(arr[j]() + " ");
} //10个10
var和let的区别在哪呢,为什么声明不一样就会变成不一样的结果呢?还有第一个函数为什么i最后都等于10了?i这里是局部变量还是全局变量呢?局部变量不应该for循环完就自动被GC了吗 还是说第一个函数存在闭包所以保留了对i的引用,所以i不会被GC了
var arr = [];
for(**let** i = 0; i < 10; i++){
arr[i] = function(){
console.log(i);
};
}
for(var j = 0; j < arr.length; j++){
console.log(arr[j]());
}//0-9
var 存在变量提升,所以你写的
等同于
实际上就是定义了一个全局变量。
虽然你return的是i,但是你在调用arr[i]这个函数的时候,会沿着作用域链找到arr[i]这个函数的上一层作用域,在这里即是全局作用域。所以你调用的时候var已经是10了,可以在 for循环后面添加一个console.log(i)验证。
let 会创建一个作用域。则,这里就会形成一个闭包
所以,使用let定义时,则分成了三层 Global --> Closure --> Local 作用域
所以你在调用arr[i]这个函数时,其实会根据作用域链找到Closure(闭包)中的 变量 i 。
使用下面这行代码,打开浏览器中的Source面板并查看右侧的Scope(作用域链)验证。
ps:个人理解,如有错误,希望指出