[英]Weird closure behavior with loop
所以我已經在這里學到了很多關於閉包的知識。
但是我仍然找到一個我自己無法解釋的例子:
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。
但是結果是:
項目:3我的值:2,列表[i]:未定義,我在匿名函數中的值:3
項目:3我的值:2,列表[i]:未定義,我在匿名函數中的值:3
項目:3我的值:2,列表[i]:未定義,我在匿名函數中的值:3
為什么我要為var item => 2而我要在匿名函數=> 3中? 在我閱讀時,閉包創建了新的執行環境,但是我不應該為閉包使用相同的值嗎?
編輯
這不是循環內JavaScript閉合的重復-簡單的實際示例 ,我不知道如何創建新的執行環境。
我想知道為什么同一變量i(循環)的值在同一范圍內不同?
當您將新函數添加到result
列表中時,它會保留對item
變量的引用,並且i
計數。 在buildList
函數內部的循環期間,您不會創建幾個item
變量,但是您會覆蓋現有的變量,在buildList
函數的item
和i
變量執行值的末尾看起來像這樣:
並且list[i]
是undefined
因為您的列表長度是3,沒有list[3]
項。 因此,當您從testList
的循環中調用匿名函數時,將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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.