下面这段code 来自阮一峰大大的ECMAScript 6 入门,讲的是let的用法 第一种: var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a [6] (); // 10 第二种: var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a [6] (); // 6 阮大大给出的解释是: 变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。这个是可以理解。
我的疑问是:let声明的10个i为什么没有被释放掉? 我的理解: 因为function 函数是在for块内,所以function 可以访问for中的局部变量 i。而function又被赋值给了全局变量a[],这就会导致那个10个不同的 i 不会被回收掉。 那么这算不算是一种闭包?
这个不叫闭包,叫作用域。
这是block scope里的 let loops 参考You don’t know js
for (let i=0; i<10; i++) {
console.log( i );
}
console.log( i ); // ReferenceError
可以理解为
{
let j;
for (j=0; j<10; j++) {
let i = j; // re-bound for each iteration!
console.log( i );
}
}
PS: 别看阮一峰了
首先感谢楼上两位小伙伴的回复。 我完全可以理解 let 的作用, 我的疑问是在为什么第二种 i 为什么没有被释放掉。楼上两位小伙伴的讨论都是let 作用域的问题。 我想知道的是 a[6] 这里发生了什么
@CollapsarLi 因为console.log( i )引用到了, i 就不会被回收
我们可以换一种方式
var a=[];
for(let i = {count: 0}; i.count < 10; i.count++) {
a[i.count] = function() {
console.log(i, i.count);
};
}
a[6](); // {count: 10} 10
很显然,在for语句中的i没有被释放掉,而且因为传对象引用,所有a都拿到了同一个i对象 这确实是形成了一个闭包(a[i.count]函数内部引用了外部的变量(i)) 因此i不会被释放掉 可以用调试工具一步步查看这个过程
var 是 function scope let 是 block scope
感谢楼上各位大佬的指点。已经理解这个问题了
一个引用自由变量的函数就是闭包。
好好体会下「自由变量」
变量执行环境