就像先前在这里所说:JavaScript closure inside loops – simple practical example
此代码的输出始终为3
var funcs = [];
for (var i = 0; i < 3; i++) { // let's create 3 functions
funcs[i] = function() { // and store them in funcs
console.log("My value: " + i); // each should log its value.
};
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
// My value: 3
// My value: 3
// My value: 3
这种情况是因为循环的匿名函数内的全局i
和i
之间没有区别。因此,当funcs[i]
被调用时,其当前值已经是3
。
解决这个问题的经典方法是通过闭包。
var funcs = [];
function createfunc(i) {
return function() { console.log("My value: " + i); };
}
for (var i = 0; i < 3; i++) {
funcs[i] = createfunc(i);
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
通过将函数创建包装在createfunc(i)
函数中,可以确保“i”的值绑定到函数外部的不变值。
解决这个问题的一种方法是通过创建let
变量来解决这个问题。
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = function() {
console.log("My value: " + i);
};
}
funcs[0]();
funcs[1]();
funcs[2]();
funcs[3]();
通过这样做,我希望变量let
在循环中只能 ,因此在我调用函数i
时仍然undefined
。
由于它有效,看起来JS能够在仍然在for循环中时分配适当的变量i
,并且在我调用函数时它已经分配了适当的值i
。
我错过了什么?