簡體   English   中英

在javascript匿名方法中訪問復制的整數變量

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM