2012-12-24 92 views
-2

可能重複:
Closures in a for loop and lexical environment使用閉包變量

我學習閉包在JavaScript中......只見例如簡單的代碼:

for (var i = 0; i < 10; i++) { 
    document.getElementById('box' + i).onclick = function() { 
    alert('You clicked on box #' + i); 
    }; 
} 

但是究竟發生了什麼,無論你選擇什麼div你都會得到一個al關於最後一個i - 最後一次迭代。

我看到內部函數的解決方案,但爲什麼會發生這種情況?是否在每次迭代中都沒有約束onclick事件?

+0

搜索'[javascript]回調循環最後值'。不缺重複。 – 2012-12-24 05:31:00

+0

-1因爲,既然你知道*關於閉包,這將很容易找到重複的。嘗試使用搜索功能或在創建帖子時查看「類似問題」。 – 2012-12-24 05:33:24

回答

1

每次迭代都會創建一個新函數,但每個函數都參考相同的變量i(內存中的位置)。 i的值僅在處理程序執行時進行評估。在for循環結束之後的那一刻,i的值爲10

Wikipedia's article about closures值得一讀,並提到閉包可以工作的兩種方式:通過綁定變量的當前值或引用變量本身。後者就是JavaScript的情況。

+0

最後一段在上下文中略有誤導。例如,在Scala和C#中,閉包也「綁定到變量的引用」。區別在於[特定]變量的範圍。 – 2012-12-24 06:05:24

+0

嗯,我可能過於簡單了一點,但我認爲它有助於理解差異,不是嗎? –

+0

我並不是說這是不正確的 - 答案仍然是我的最高票數。對於未來的讀者來說,這只是一個記錄。 – 2012-12-24 06:13:48

0

良好的舊同變量問題。 - JavaScript的唯一具有的功能範圍

for(var i = 0; i < 10; i++) { 
    (function(i) { 
     document.getElementById('box' + i).onclick = function() { 
      alert('You clicked on box #' + i); 
     }; 
    })(i); 
} 

之所以這樣,是必要的工作原理是,i通常總是相同的:您可以輕鬆地將其通過取i作爲參數自調用函數繞過它。通過使用以i作爲參數的自我調用函數,您每次都會創建一個新的i,然後將其保存在回調函數的閉包中。

+0

我會*愛*看到誰downvoted這個評論。 – ThiefMaster