所以我已经在SO上学到了很多关于闭包的知识。
但我仍然找到了一个我无法向自己解释的例子:
function buildList(list){
var result = [];
for(var i = 0; i < list.length; i++) {
var item = "item: " + list[i] + " i's value: " + i; //i has the value of 2 here, but why?
result.push( function(){document.write(item + ", list[i]:" + list[i] + ", i's value in the anonymous function:" + i + "<br>")});
} //i = 3 here
return result;
}
function testList(){
var testTheList = buildList([1,2,3]);
for (var j = 0; j < testTheList.length; j++) {
testTheList[j]();
}
}
testList();
正如我所期望的那样,当我执行testList()时,我应该是3。
但结果是:
item:3我的值:2,list [i]:未定义,我在匿名函数中的值:3
item:3我的值:2,list [i]:未定义,我在匿名函数中的值:3
item:3我的值:2,list [i]:未定义,我在匿名函数中的值:3
为什么我是var item =&gt; 2和i里面的匿名函数=&gt; 3?正如我所读到的,闭包创建了新的执行环境,但是我不应该为闭包创建相同的值吗?
修改
这不是JavaScript closure inside loops – simple practical example的重复,我不想知道如何创建新的执行环境。
我想知道为什么同一个变量i(循环)的值在同一范围内有所不同?
答案 0 :(得分:0)
当您将新功能添加到result
列表时,它会保留对item
变量和i
计数器的引用。在buildList
函数内的循环期间,您不会创建少量item
个变量,但是在buildList
函数执行值item
结束时,您将覆盖现有变量和i
变量看起来像这样:
list[i]
为undefined
,因为您的列表长度为3,您没有list[3]
项。因此,当您在testList
中循环调用匿名函数时,它会重新生成与item
和i
变量完全相同的值。还要在循环中创建匿名函数,这不是最佳做法,我建议您修改buildList
函数,如下所示:
function buildList(list) {
var index = 0;
return function () {
if (index >= list.length) return
var item = "item: " + list[index] + " i's value: " + index;
document.body.innerHTML += [
item, ", list[i]:", list[index],
", i's value in the anonymous function:",
index, "<br>"
].join('')
index++
}
}
function testList() {
var list = [1, 2, 3];
var testTheList = buildList(list);
document.body.innerHTML = '';
for (var j = 0; j < list.length; j++) {
testTheList();
}
}
testList();
&#13;