setTimeout 學習閉包
@(技術筆記)[css]
學習參考網站
var create = function (i){
return function(){
console.log(i);
};
};
for ( var i = 0; i < 5; i++ ) {
console.log(i);
setTimeout( create(i), i * 1000 );
}
上面代碼運行解釋:
這是一個倒計時代碼片段!
javascript的到計時代碼并不是那么好寫的哈。呵呵
setTimeout 是一個異步執行的函數。函數定義如下:

第一個參數是要執行的方法(function),第二個參數是延遲時間。
好的。那我們這樣寫會有什么結果:
for ( var i = 0; i < 4; i++ ) {
setTimeout( function () {console.log(i)}, i * 1000 );
}
輸出結果為
4
4
4
4
我是這樣理解的,setTimeout函數式異步函數,它會在for循環結束后執行。這時候在運行棧中的匿名函數i的值為4,所以運行的結果都為4。
步驟如下:
- 第一個for循環,在棧中壓入帶執行的方法
setTimeout( function () {console.log(i)}, i * 1000 );
此時i為1. - 第二次for循環,在棧中壓入待執行的方法
setTimeout( function () {console.log(i)}, i * 1000 );
此時i為2。這個i是個全局變量,所以此時第一壓入棧中的函數i也為2.
以下重復上面步驟,最后壓入棧中待執行的函數指向的變量值都為4.
所以最終的輸出結果為 上面所示。
那么我們如何才能輸出4個不一樣的值呢?
如何讓函數保存住它的變量。
for (var i = 0; i < 4; i++) {
setTimeout(create(i), i * 1000);
}
create(i) 是執行函數create并傳入參數i,這個函數會立刻執行,這個函數執行完后有一個返回值。這個返回值也是一個函數,這個函數保存了i變量,這個i變量不會變。它的作用域在這個返回的匿名函數。此時i為1.
剩下同理,函數保存了變量的值。所以這次執行結果會按照我們開始設想的那樣輸出:

這里用閉包保存變量的值。
浙公網安備 33010602011771號