我喜歡做的事情大致如下:Javascript:關閉循環?
for(var i = 0; i < 10; ++i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
的這個是,我總是得到的i
終值,因爲Javasript的關閉是沒有價值的。
那麼我怎樣才能做到這一點與JavaScript?
我喜歡做的事情大致如下:Javascript:關閉循環?
for(var i = 0; i < 10; ++i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
的這個是,我總是得到的i
終值,因爲Javasript的關閉是沒有價值的。
那麼我怎樣才能做到這一點與JavaScript?
for(var i = 0; i < 10; i++) {
(function(i) {
createButton(function() { alert("button " + i + " pressed"); });
})(i);
}
注意的JSLint不喜歡這種模式。它會拋出「不要在循環中創建函數」。
因爲它的清潔,我比Peter更喜歡這個答案。如果更多瀏覽器支持'let'關鍵字,那將會很好。 – McStretch 2011-04-05 17:13:20
@McStretch我試圖在jsFiddle中做一個'let'演示,但是我無法讓它工作。看到這裏:http://jsfiddle.net/simevidas/ZKeXX/1/ Firefox 4會引發錯誤。 – 2011-04-05 17:31:03
@Šime - 我剛剛看到這個問題:http://stackoverflow.com/questions/2356830/what-browsers-currently-support-javascripts-let-keyword,它說你必須明確地告訴瀏覽器(Firefox現在只有現在)你使用的是1.7。這是一個更新的小提琴:http://jsfiddle.net/simevidas/ZKeXX/1/。很蹩腳吧?顯然,直到每個人都支持1.7或更高版本,並且知道何時會發生,這不是一個很好的解決方案。 – McStretch 2011-04-05 17:52:54
您需要將閉包放入單獨的函數中。
for(var dontUse = 0; dontUse < 10; ++dontUse) {
(function(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
})(dontUse);
}
Thise代碼創建一個匿名函數,它i
作爲用於循環的每次迭代的參數。
由於這個匿名函數爲每次迭代都有一個單獨的i
參數,因此它解決了這個問題。
這相當於
function createIndexedButton(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
for(var i = 0; i < 10; ++i) {
createIndexedButton(i);
}
for(var i = 0; i < 10; ++i) {
createButton(x, y, (function(n) {
return function() {
alert("button " + n + " pressed");
}
}(i));
}
在外面的匿名功能將自動調用並在其範圍內,在那裏,它利用每個i
的然後當前值創建具有n
一個新的閉合它被調用的時間。
通過執行另一個函數創建關閉一個新的範圍:
for(var i = 0; i < 10; ++i) {
createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}
1。您可能希望在return語句的末尾放置一個分號,以使代碼更具可讀性。 2. IIFE通常包裹在parens中。 – 2011-04-05 17:02:18
@Šime,是的,我同意。 – 2011-04-05 17:07:30
一個解決方案,如果你的編碼爲使用JavaScript 1.7或更高版本瀏覽器,是使用let
關鍵字:
for(var i = 0; i < 10; ++i) {
let index = i;
createButton(x, y, function() { alert("button " + index + " pressed"); }
}
從MDC文件中心:
let關鍵字導致項目 變量與塊0一起創建級別作用域,導致爲for循環的每次迭代 創建一個新的引用 。這意味着每個 閉包都會捕獲一個單獨的變量,從而解決共享環境造成的問題。
查看MDC Doc Center的傳統方法(創建另一個閉包)。
您可以編輯createButton,允許它傳遞另一個參數,即i。這樣你可以將我存儲在你的createButton函數中並使用它。 – rsplak 2011-04-05 16:55:09
[Javascript閉包內循環 - 簡單實用示例]的可能重複(http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – rds 2013-01-17 17:53:41