2017-04-10 99 views
0

請忽略這樣的事實,即這段代碼什麼都不做,並且對可能是一個瘋狂的問題表示歉意!爲什麼我不能將函數調用(而不是函數引用或匿名函數)傳遞給setTimeout()?

據我所知,我不能通過函數調用setTimeout()作爲第一個參數,但爲什麼我不能這樣做?

let names = ['Andy', 'Ross', 'David']; 

function printer (name) { 
console.log(name); 
} 

names.forEach(name => setTimeout(printer(name), 1000); 

結果:

Andy 
timers.js:327 
    throw new TypeError('"callback" argument must be a function'); 
    ^

我可以解決,而不是使用參考printer使用bind()送與它一起name的問題,但我爲什麼一定要把這些額外的步驟?

let names = ['Andy', 'Ross', 'David']; 

function printer (name) { 
    console.log(name); 
} 

names.forEach(name => setTimeout(printer.bind(null, name), 1000)); 

結果:

Andy 
Ross 
David 
+0

因爲setTimeout應該會收到一個應該稍後調用的回調 –

回答

1

你可以試試這個:

setTimeout(function(){printer(name)}, 1000) 
0

你可以這樣說:

setTimeout(printer, 1000, name) 
0

傳遞函數引用的正確方法是使用回調。

names.forEach(name => setTimeout(function() { 
    printer(name); 
}, 1000)); 

回調包含對函數的引用。

setTimeout(callbackFunction, milliseconds); 
2

這是因爲執行的順序。如果您將函數調用傳遞給setTimeout,則該函數將立即執行,即該函數立即放入JavaScript的執行堆棧中。

如果您傳遞函數名稱,即對函數的引用,則只有在定時器完成後纔會將函數放入JavaScript線程的執行堆棧中。

+0

謝謝,這很有道理!我很感激 – NoobOfNoobs

相關問題