在下面的代码中,我将回调函数添加到循环中的列表中。
我呼叫回拨的列表中的每个项目都会记录>> item30
new function()
它可以记录
item0
item1
item2
item3
item4
and so on .......
...
for (var j = 0 ; j < 30 ; j += 1) {
addThisThingtoList(function () {
console.log( "item" +j );
});
}
答案 0 :(得分:2)
只有在函数addThisThingtoList()
使用异步行为(如Ajax调用)时才会发生这种情况,因此在for
循环完全运行之后的某个时间调用它的回调,因此它的索引值是在结束值。
您可以使用一个闭包修复它,该闭包会为每次调用addThisThingtoList()
分别冻结循环值,如下所示:
for (var j = 0 ; j < 30 ; j += 1) {
(function(index) {
addThisThingtoList(function () {
console.log( "item" + index);
});
})(j);
}
工作演示:http://jsfiddle.net/jfriend00/A5cJG/
作为解释,这是IIFE(立即调用的函数表达式)。变量j
被传递给IIFE,它成为我命名为index
的函数的命名参数。然后,在该函数内部,您可以将index
称为j
的值,该addThisThingtoList()
的值是唯一且为每次index
调用而单独冻结的。我可以将参数j
命名为j
,在这种情况下它会覆盖更高范围的{{1}},但我更喜欢使用单独的变量名来更清楚什么是。
如果您想了解更多信息,请参阅IIFE概念:
http://benalman.com/news/2010/11/immediately-invoked-function-expression/
答案 1 :(得分:1)
这就是封闭的全部意义。
当你调用该函数时,它会在调用时拉出j
的值,而不是在它被添加到列表时。
因此,当您开始调用函数时,j已经是30。
答案 2 :(得分:0)
这是一个经典的JavaScript范围错误。您需要将j变量传递给您的函数:
addThisThingToList(function(j) {
console.log("item" + j);
});
正如@Smeegs所说,&#34;这就是封闭的全部意义。&#34;