2017-04-02 64 views
2

在下面的代碼我感到困惑與註釋的行「在這裏!」:當索引是閉包的一部分時,如何創建索引?

var foo = []; 
for(var i = 0; i < 10; i++){ 
    (function(){ 
    var y = i; 
    foo[i] = function(){return y;} //here! 
})(); 
} 

爲什麼「我」價值創造「富」正確的指標?在當我們試着去請教它的價值到底是10.那麼,爲什麼don'tnwe有類似:FOO的

內容:富[10] // 10(有此數組中僅此位置)

我知道我們有一個關於「我」的關閉,因爲我們正在做一個有關另一個範圍的參考,,但是我不明白的是爲什麼「foo」的索引被正確創建並關閉了「我「變量。

+0

你IIFE執行每次迭代後立即,並使用i'的'當前值。只有在IIFE內創建的內部函數需要閉包才能正常工作,因爲這些函數稍後會被調用(儘管顯示的代碼從不會調用它們)。 – nnnnnn

回答

0

我想看看在循環的單次迭代是非常有用瞭解正在發生的事情。

比方說i = 3

您創建一個匿名函數並分配y = i這使得y點值3,即。之後y的值不取決於i。然後你設置foo[3] = function() {return y; // return 3。關鍵是i更改不會更改y的值。

這裏唯一相關的關閉是允許foo[i]訪問y,儘管外部匿名函數已被完全執行和完成。

另請注意,每次迭代都會聲明一個新的var y,它指向i中的的值,該值僅爲。所以每個函數都會在單獨的執行上下文中返回一個單獨的y


比較到下面的代碼,其不具有一箇中間變量(如在代碼中y)等ii實際值在封閉範圍 - 即,10的i循環後的值已經完成

for(var i = 0; i < 10; i++){ 
    (function(){ 
    foo[i] = function(){return i;} 
})(); 
} 

foo[3] = 10; // as you expected for your code 

又如下面是與你相似,並具有相同的行爲,參數到外匿名函數保持其內在功能被關閉了的值。

for(var i = 0; i < 10; i++){ 
    (function(x){ 
    foo[i] = function(){return x;} 
})(i); // notice that we pass i in here 
} 

foo[3] = 3; 
0

爲什麼i價值創造的正確foo指數:

在javascript中的列表只是一個底下的對象。在變量上使用[]訪問器可創建從[]的內容到指定值的映射。您正在將密鑰i映射到返回值y的函數。

爲什麼創造了foo索引正確有過i變量封閉:

你是存儲在循環函數的引用。如果你要做到以下幾點,我相信你會得到你所期望的結果:

foo[10]() // This will return 10. 

參考文獻:

Insert into array at non-existent index

1

它工作的原因是您的內部函數在循環內同步調用。發生

常見問題 - 在一個嵌套函數引用的外索引 - 當該功能被稱爲異步,或至少後的循環已經執行完畢,這是不你的情況。

例如其中出問題:

var foo = []; 
for(var i = 0; i < 10; i++){ 
    setTimeout(function(){ 
     var y = i; 
     foo[i] = function(){return y;} //here! 
    }, 0); 
}