function box() {
var arr = [];
for (var i = 0; i < 5; i++) {
arr[i] = function () {
return i;
}
}
return arr;
}
var b = box();
for (var i = 0; i < 5; i++) {
alert(b[i]);
}
Nachdem box() ausgeführt wurde, warum sind die Werte in arr[0] bis arr[4] alle function () { return i;}
Warum sind sie nicht: function () {return 0;}, function ( ) {return 1;}. . .
因为闭包只能取得包含函数中任何变量的最后一个值,在这里指的就是i这个变量,box()函数执行后返回的是一个函数数组,数组中的每一个i引用的都是同一个变量i,注意box()返回的是一个函数!所以里面的{return i}这只是函数内的一个声明,还没有执行呀,所以当然保持{return i}不变。因为引用的是同一个外部i,所以当box()函数返回后,外部变量i的值是5,此时每一个return中都引用着保存变量i的同一个变量对象,所以如果最后执行了内部的arr[]中的函数,最后每个函数内部的i的值都是5.
因为关联到闭包的作用域链是"活动的". 并且他们共享变量 i , 并不是对每个绑定的变量的值赋值自己单独的一份. 他们只是引用 i,并不会保存 i 每个阶段的值.
参考书籍: JavaScript 权威指南 8.6 小节.
示例中for循环里的function只是赋值,并没有执行,所以当数组中函数执行时才去获取i的值,这时候i只有循环结束的值,楼上没有用到闭包,只是用一个立即执行的匿名函数得到了每个循环的i的值;
方法:1.用ES6 let替代var
function box() {
2.采用闭包
function box() {
。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域) ---百度百科
意思就是
这个就是一个代码块,作用仅仅是他引用了i,这样持有i就会导致i不会被释放掉,我们保存的只是这个代码块,这个代码块不运行之前,他根本不知道i是什么东西,就有他运行的时候,他才会去找i,所以你可以把你的arr都输出一下,应该输出的全是5
调用的时候才计算
i
是什么。而在调用这些函数的时候,
for
已经结束,因此取i
的时候值是5