2011-01-19 36 views
1

我的代碼看起來像這樣:重新定義一個局部變量在javascript關閉

for(var i=0; i<10; i++) { 
    var someClickableObject = new Object(); 
    someClickableObject.index = i; 

    eventListenerFunction(someClickableObject, 'click', function() { 
     alert(someClickableObject.index); 
    }); 
} 

所以我創建了一堆可點擊的對象,給每個等於循環索引的屬性,上設置點擊事件提醒其索引屬性的對象。

我希望每個對象都能提醒創建它的索引i。相反全部對象警報9.我認爲這是因爲事件偵聽器在每次迭代中重新定義的對象上形成一個閉包。

關於如何解決這個問題的任何想法?

回答

1

問題實際上與您所寫的相反:全部功能共享相同關閉。 (編輯 —重新閱讀你寫的內容後,我不確定它是否與任何東西「相反」;關鍵是你傳遞給「eventListenerFunction」的所有這些小函數將共享相同的變量「someClickableObject」 ,所以在循環結束時,他們都會指在最後一次迭代創建的)

要解決它,你需要引入某種方式的另一個範圍:

eventListenerFunction(someClickableObject, 'click', (function(obj) { 
    return function() { 
    alert(obj.index); 
    }; 
})(someClickableObject)); 

,介紹一個匿名功能。通過引用局部變量來調用這個小函數,該函數的作用是創建另一個範圍。該函數返回實際傳遞給該「eventListener」事物的函數。它現在有自己的「someClickableObject」副本。

然而,它只是一個副本。在你的情況下,這沒關係,因爲你在每次迭代中創建一個新對象。在實踐中,我幾乎從不擔心這種情況;通常我只需要擔心一個淺拷貝(因爲它通常只是一個計數器,或者一個字符串鍵值,或者類似的東西)。

+0

你的好。謝謝。 – opl 2011-01-19 16:11:26