[英]Access a copied integer variable in javascript anonymous method
我是C#開發人員,習慣於C#中的閉包工作方式。 目前,我必須使用匿名javascript函數並遇到以下代碼段問題:
function ClosureTest() {
var funcArray = new Array();
var i = 0;
while (i < 2) {
var contextCopy = i;
funcArray[i] = function() { alert(contextCopy); return false; };
i++;
}
funcArray[0]();
funcArray[1]();
}
我希望第一個funcArray()
調用說0
,第二個要說1
。 但是,他們都說1
。 那怎么可能?
通過編寫var contextCopy = i
,可以確保創建i
變量的副本。 然后,在每個while迭代中,我創建一個全新的函數指針。 每個函數都引用自己的i
副本, i
contextCopy
。 但是,由於某些原因,兩個創建的函數都引用相同的contextCopy
-variable。
這在javascript中如何運作?
JavaScript具有詞法閉包,而不是塊閉包。 即使您將i分配給contextCopy,contextCopy本身也是ClosureTest的詞匯成員(與C#不同,在C#中,{}為您提供了一個新的作用域塊)。 嘗試這個:
while (i < 2) {
funcArray[i] = (function(value) {
return function(){ alert(value); return false; }
})(i);
i++;
}
JavaScript中的花括號( {}
)不能像在C#中那樣捕獲變量。
僅閉包(函數)引入新的作用域並捕獲變量。
var i = 0;
while (i < 2) {
var contextCopy = i;
...
}
實際上被解釋為:
var i, contextCopy;
i = 0;
while (i < 2) {
contextCopy = i;
...
}
要獲取變量的副本,您需要使用閉包將代碼包裝起來:
var i;
i = 0;
while (i < 2) {
(function (contextCopy) {
...
}(i));
}
您不會創建i變量的副本。 取而代之的是,使此變量依賴於使用它的閉包成為GC。 這意味着,當while循環退出時,i變量繼續處於其最后一個狀態(1),並且兩個閉包均引用該變量。
放置它的另一種方式:關閉變量不會將其復制到閉包中(對對象幾乎沒有意義),它只是使閉包引用該變量,並確保在閉包存在之前,該變量不會被GC化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.