對迴圈中setTimeout執行過程的思考
題目
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
答案
每隔一秒輸出5
分析
由於setTimeout會延遲執行,所以處理結果是執行迴圈之後再將裡面的函式壓入事件佇列。執行迴圈的時候壓入佇列的函式是:0s console.log(i);1s console.log(I);….所以每隔一秒輸出i。而由於i是var型別的,由於變數提升,最後的i都變成5了。於是最後都列印5
如果將上面的程式碼變成這樣:
for (let i = 0; i < 5 ; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
顯然是每隔一秒輸出0,1,2,3,4了,因為let存在塊級作用域。
那麼將程式碼變成這樣呢?
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}
由於setTimeout裡面是立即執行函式,於是便不會根據時間延遲將函式壓入佇列,而是直接進入事件迴圈執行。所以會直接進行輸出0,1,2,3,4。