我很想解释一下(取自javascriptkit.com):
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])} );
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
所以testList()
非常简单。
我尝试一步一步地遵循第一个功能,这就是我认为会返回的内容:
项目1 1
项目2 2
项目3 3
我得不到的是result
如何以item 3 undefined
3次返回 - 为什么未定义,为什么只有item 3
?
- 正如我正在努力学习的那样,我不打算让它发挥作用,而是要明白我错过了什么部分,以及为什么它不像我期望的那样出现。
答案 0 :(得分:4)
有什么问题?
for循环中的函数引用i
,但i
在每次迭代中都在变化,所以当你调用循环中声明的函数时,它会使用i
。最后一个值(3)。
一个简单的闭包将保持索引值不受影响:
for (var i = 0; i < list.length; i++) {
(function(index){
var item = 'item' + list[index]; // why ?
result.push( function() {alert(item + ' ' + list[index])} );
})(i);
}
注意:强>
如果重新查找列表中的值,为什么需要var item = 'item' + list[index];
?
更新,
因为i
具有最终值-3,这使得您的代码进入最后的迭代:
// i equals to 2 here
var item = 'item' + list[i]; // gives item3
result.push( function() {alert(item + ' ' + list[i])} );
// now `i` is changed to three so we don't enter the loop.
值:
item
== "item3"
i == 3
list[i]
== list[3]
== undefined
。答案 1 :(得分:1)
重要的是要理解buildList
返回的数组包含共享相同闭包的3
函数。每次关闭该闭包的局部变量时 - 它会影响共享它的所有函数。换句话说,结果中所有函数的i
,item
和list
变量都是相同的。在循环遍历list
之后,i
的值保持等于3
,result
中的所有函数都为真,因为它们共享对该变量的引用。所以,你问题的答案就是这样:
为什么未定义?
因为list[3] === undefined
为什么item 3
?
因为上次修改item
变量的时间是i
2
而for
已执行其正文(list[2] === 3
因此item === 'item 3'
)< / p>