這是一個很常見的問題,人們打了。
麻煩的是,你傳遞給setTimeout
在每次迭代函數引用相同i
變量。
JavaScript沒有塊範圍,只有函數範圍。因此,要創建一個新的範圍,將保留您想要的i
值,您需要在循環內調用一個函數,並將其傳遞給i
。
例子:http://jsfiddle.net/GNwhR/3/
function set_up_timeout(j) {
setTimeout(function(){
delayedLoad(j);
},3000*j);
}
function loadContent(){
var i,
len = 3
for (i = 0; i < len; i++) {
console.log(i);
set_up_timeout(i);
}
};
這會將你的電話setTimeout
中被調用,並在每次迭代通過i
另一個函數。這將創建一個新的變量範圍,其中該函數中的j
引用了正確的值。
另一種方法是讓調用函數回功能:
例子:http://jsfiddle.net/GNwhR/4/
function set_up_callback(j) {
return function(){
delayedLoad(j);
};
}
function loadContent(){
var i,
len = 3
for (i = 0; i < len; i++) {
console.log(i);
setTimeout(set_up_callback(i), 3000*i);
}
};
這一個電話set_up_callback
,這回報一個函數引用j
。
最後,另一種常見的方法是使用一個IIFE (立即調用函數表達式)消除命名的函數。這是不太清楚IMO:
實施例:http://jsfiddle.net/GNwhR/5/
function loadContent(){
var i,
len = 3
for (i = 0; i < len; i++) {
console.log(i);
setTimeout((function(j){
return function() {
delayedLoad(j);
};
})(i),3000*i);
}
};
這是基本相同的,因爲它返回一個函數前面的例子。主要區別在於返回函數的函數在循環內部創建並調用。
所有這些說明了同樣的概念,你如果你希望以後異步引用它,並將它保持其預期值需要範圍的變量。
@帕特里克....這是一個非常好的解釋。在我等待答案時,我設法解決了這個問題......就像我說的那樣應該很簡單......我真的不應該在週日晚上編寫代碼。 –
@詹姆斯:啊,好的。很高興你明白了。 – user113716