我想要傳遞變量setTimeout
函數並對其進行處理。當我提醒i
的價值時,它會顯示我沒有預期的數字。我做錯了什麼?我想記錄從1至值8如何將變量傳遞給匿名函數
var end=8;
for (var i = 1; i < end; i ++) {
setTimeout(function (i) {
console.log(i);
}, 800);
}
我想要傳遞變量setTimeout
函數並對其進行處理。當我提醒i
的價值時,它會顯示我沒有預期的數字。我做錯了什麼?我想記錄從1至值8如何將變量傳遞給匿名函數
var end=8;
for (var i = 1; i < end; i ++) {
setTimeout(function (i) {
console.log(i);
}, 800);
}
setTimeout
接受變量作爲附加參數:
setTimeout(function(a, b, c) {
console.log(a, b, c);
}, 1000, 'a', 'b', 'c');
編輯:在你的例子中,i
的有效值很可能是8
,因爲函數只是在循環完成後調用。你需要傳遞的i
的當前值每個呼叫:
var end=8;
for (var i = 1; i < end; i ++) {
setTimeout(function (i) {
console.log(i);
}, 800, i);
}
請記住,雖然「**請注意,在第一種語法中向函數傳遞附加參數在Internet Explorer中無效**」 – 2012-04-18 10:35:10
對於IE,您總是可以使用舊的(但已棄用的)語法:'setTimeout('可調用('+ i +')',1000);'。 – Iso 2012-04-18 10:36:45
這甚至不能在** IE9 **中工作,遠不及早期版本。這個答案在2018年左右的某個時候可能會有用。 – 2012-04-18 10:41:54
解決這個標準的方法是使用一個工廠函數:
var end=8;
for (var i = 1; i < end; i ++) {
setTimeout(makeResponder(i), 800);
}
function makeResponder(index) {
return function() {
console.log(index);
};
}
在那裏,我們呼叫makeResponder
在循環,並返回其關閉在傳遞給它(index
)的說法,而不是i
變量的函數。 (這很重要,如果你剛剛從你的匿名函數中刪除了i
參數,你的代碼將會部分工作,但是所有函數在運行時看到i
的值,而不是當它們最初被調度時;你的榜樣,他們會都看到8
)
更新從下面您的意見:
... ...它是正確的,如果我以這種方式
setTimeout(makeResponder(i),i*800);
打電話了嗎?
是的,如果你的目標是讓每個電話大約在800ms出現比上一個後,將工作:
我試圖
setTimeout(makeResponder(i),setInterval(i));function setInterval(index) { console.log(index*800); return index*800; }
但它無法正常工作
不要使用setInterval
這種方式,並且可能不希望在所有使用它的這一點。
進一步更新:你曾經說過如下:
我需要第一次迭代打印8延遲8秒,第二次迭代打印7延遲7秒........打印2延遲2秒...打印0延遲0秒。
你只適用上述原則再次使用第二超時:
var end=8;
for (var i = 1; i < end; i ++) {
setTimeout(makeResponder(i), i * 800);
}
function makeResponder(index) {
return function() {
var thisStart = new Date();
console.log("index = " + index + ", first function triggered");
setTimeout(function() {
console.log("index = " +
index +
", second function triggered after a further " +
(new Date() - thisStart) +
"ms delay");
}, index * 1000);
};
}
我想你現在擁有所有需要的工具來推進這項工作。
嗨,謝謝,如果我以這種方式調用setTimeout(makeResponder(i),i * 800),它會是正確的嗎?我的意思是這部分我* 800,我認爲它保持不變。 – alexeyb 2012-04-18 11:02:34
我試過setTimeout(makeResponder(i),setInterval(i)); function setInterval(index){ console.log(index * 800); 返回索引* 800; }但它不能正常工作 – alexeyb 2012-04-18 11:14:30
@alexeyb:我已將答案添加到上面的問題中。 – 2012-04-18 11:34:22
這個不能正常工作的主要原因是因爲,其中setTimeout
設置爲在800
之後運行並且範圍爲i
。
當它執行時,其值i
已經發生了變化。因此沒有收到明確的結果。就像TJ說的那樣,處理這個問題的方法是通過一個處理函數。
function handler(var1) {
return function() {
console.log(var1);
}
}
var end = 8;
for (var i = 1; i < end; i++) {
setTimeout(handler(i), 800);
}
你的問題是,你指的是可變i
一段時間後,當你setTimeout()
功能火災,屆時,i
值已改變(它去了for
結束爲了保持每個setTimeout的值爲i
,您必須分別爲每個setTimeout()
回調捕獲該值i
。
上一個使用facto的答案ry函數可以做到這一點,但是我發現自執行函數比工廠函數更容易輸入和關注,但兩者都可以工作,因爲兩者都可以在閉包中捕獲所需的變量,以便您可以在setTimeout回調中引用它們的靜態值。
這裏是一個自我執行的功能將如何工作來解決這個問題:
var end=8;
for (var i = 1; i < end; i ++) {
(function (index) {
setTimeout(function() {
console.log(index);
}, 800);
})(i);
}
按比例超時延遲時間設置爲i
值,你可以這樣做:
var end=8;
for (var i = 1; i < end; i ++) {
(function (index) {
setTimeout(function() {
console.log(index);
}, index * 800);
})(i);
}
的自執行函數傳遞的值爲i
,並且該函數內包含該值的參數被命名爲index
,因此您可以參考index
以使用適當的值。
這是正確的?你有什麼錯誤嗎? – Starx 2012-04-18 10:33:52
你的問題是一個範圍問題:'for'計數器變量被稱爲'i',但該參數也稱爲'i'。因此,只要您在參數-i範圍內,計數器i的任何值都會被覆蓋。重命名計數器或參數應該有所幫助。 – 2012-04-18 10:34:15
@DominikSchreiber:這是部分*範圍問題。但只是刪除或重命名'我'參數不會解決它。 – 2012-04-18 10:42:31