可能重複的:
setTimeout in a for-loop and pass i as value的setTimeout不打印連續的數字,因爲封閉
for (var i = 0; i < 5; i++) {
setTimeout(function (i) {
console.log(this.i)
}, 1000);
}
這將打印5
五倍。我如何編寫循環以便打印0, 1, 2, 3, 4
?
可能重複的:
setTimeout in a for-loop and pass i as value的setTimeout不打印連續的數字,因爲封閉
for (var i = 0; i < 5; i++) {
setTimeout(function (i) {
console.log(this.i)
}, 1000);
}
這將打印5
五倍。我如何編寫循環以便打印0, 1, 2, 3, 4
?
包裝在一個自執行關閉:
for (var i = 0; i < 5; i++) (function(i) {
setTimeout(function() {
console.log(i)
}, 1000);
})(i);
注:未使用的參數的函數表達式setTimeout的,所以我把說出來。另外,使用全局變量並不好。使用var
關鍵字創建變量。
您也不需要this.i
;只需使用i
即可。
不起作用:http://jsfiddle.net/eRYKk/ – CodePB
現在確實如此。我擺脫了'this.i',並用'i'代替了它。 – 0x499602D2
不,OP希望它能夠以間隔工作。 – dfsq
試試這個:
var i=0;
var fn;
fn=function(){
console.log(i)
i++;
if(i<=4)setTimeout(fn,1000);
}
setTimeout(fn,1000);
將輸出一個數字每秒鐘五次。
像這樣:
for (var i = 0; i < 5; i++) {
(function (i) {
setTimeout(function() {
console.log(i)
}, 1000);
})(i);
}
這裏最重要的因素是,的JavaScript只有函數範圍 *,所以要創建範圍是不同的,每循環是包裝的膽量的唯一途徑在一個函數中循環。這樣,你的setTimeout
函數爲該循環的迭代創建了一個圍繞i
的閉包。
編輯:
*的let
關鍵字在ES6,讓你聲明塊範圍局部變量的能力來。如果沒有啓用實驗性功能,Chrome 31不支持它,所以請務必check compatibility。
現在錯了。 JavaScript也具有像catch()這樣的塊範圍,從EF6開始,可以使用'let'來代替'var'來爲幾乎所有其他類型的塊提供塊範圍,例如'for's和'if's 。 – Jazcash
錯了?我建議不要在瀏覽器應用程序中使用'let'關鍵字,因爲在許多瀏覽器(包括Chrome 31)中(尚未啓用實驗性標誌)尚不可用。也許你可以通過發佈一個使用'let'關鍵字並解釋權衡的答案來爲社區提供更多的價值。 http://kangax.github.io/es5-compat-table/es6/ –
現在忽略'let',就像我說的那樣,'try','catch'仍然存在範圍。我認爲這是在EF6以前的版本中,除了'function'之外的唯一其他塊。 我不是JS專家,但您的聲明'JavaScript只有函數範圍'是錯誤的,儘管非常微弱。 [Google's Traceur](http://code.google.com/p/traceur-compiler/)爲EF6之前的其他塊提供了範圍,它使用'try','catch's來完成。 – Jazcash
這個問題每天要問好幾次。 – epascarello