for循環中的閉包問題

for循環:閉包

for (var i=1; i<=5; i++) {
   setTimeout( function timer() {
     console.log( i );
   }, i*1000 );
}

/* 控制檯打印:
    6
    6
    6
    6
    6
    6
 */

可是咱們但願的結果是:函數

1
2
3
4
5

緣由是,延遲函數的回調會在循環結束時才執行。當定時器運行時即便每一個迭代中執行的是setTimeout(.., 0),全部的回調函數依然是在循環結束後纔會被執行,所以會每次輸出一個6 出來。code

咱們改寫一下:作用域

for (var i=1; i<=5; i++) {
  (function() {
     setTimeout( function timer() {
        console.log( i );
     }, i*1000 );
   })();
}
/*
    6
    6
    6
    6
    6
*/

緣由:若是做用域是空的,那麼僅僅將它們進行封閉是不夠的。它須要包含一點實質內容才能爲咱們所用。它須要有本身的變量,用來在每一個迭代中儲存i 的值:回調函數

繼續改寫:io

for (var i=1; i<=5; i++) {
    (function() {
        var j = i;//保存外部變量
        setTimeout( function timer() {
            console.log( j );
        }, j*1000 );
    })();
}
/*
    1
    2
    3
    4
    5
*/
//代碼改進:(將i當參數傳進去)
 for (var i=1; i<=5; i++) {
    (function(j) {
        setTimeout( function timer() {
            console.log( j );
        }, j*1000 );
    })( i );
}

總結console

當函數能夠記住並訪問所在的詞法做用域,即便函數是在當前詞法做用域以外執行,這時
就產生了閉包。
相關文章
相關標籤/搜索