setTimeout 循環閉包的經典面試題 解法與探究

題:修改下面的代碼,讓循環輸出的結果依次爲1, 2, 3, 4, 5

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

一、利用閉包:

1.匿名函數
//隔1s
for (var i=1; i<=5; i++) { 

    (function(i) {
        setTimeout( function timer() {
            console.log(i);
        }, i*1000 );
    })(i)
}
2.setTimeout的第一個參數處利用閉包。
//隔1s輸出
for (var i=1; i<=5; i++) { 
    setTimeout( (function(i) {
        return function() {
            console.log(i);
        }
    })(i), i*1000 );
}

二、不利用閉包: 加深對setTimeout的理解

1.//瞬間輸出 
for (var i=1; i<=5; i++) { 
    setTimeout(console.log(i), i*1000 );
}//就相當於用了for循環
2..//間隔1s
for (var i=1; i<=5; i++) { 
    setTimeout( function timer(a) {
        console.log(a);
    }, i*1000 ,i);
}//setTimeout的3及以後的參數爲傳入運行中的
3.瞬間輸出
for (var i=1; i<=5; i++) { 
    setTimeout( function timer(a) {
        console.log(a);
    }(i), i*1000 )};

三.比較好玩的幾個例子對比:及更深的理解
(1).是否多個(),加個匿名函數包起來,在這裏結果是一樣的

//間隔1s
for(var i=1;i<=5;i++){
  setTimeout(function(i){
    return function(){
      console.log(i);
    };
  }(i),i*1000);
}//結果1,2,3,4,5

//多了一層匿名函數包裹
//間隔1s
for (var i=1; i<=5; i++) { 
    setTimeout( (function(i) {
        return function() {
            console.log(i);
        };
    })(i), i*1000 );
}//結果1,2,3,4,5

(2).統一加匿名包,繼續探究傳入參數的問題

//間隔1s
for (var i=1; i<=5; i++) { 
    setTimeout( (function(i) {
        return function test(i) {
            console.log(i);
        };
    })(i), i*1000 );
}
//結果5個undefined....
//test(i)會把console.log(i)中的i看作test()函數的參數,而不是作用域外面的參數
//和下面的例子是一樣的道理

for (var i=1; i<=5; i++) { 
    setTimeout( (function(i) {
        return function test(a) {
            console.log(a);
        };
    })(i), i*1000 );
}//結果5個undefined....
//間隔1s
for (var i=1; i<=5; i++) { 
    setTimeout( (function(i) {
        return function test(a) {
            console.log(i);
        };
    })(i), i*1000 );
}//結果1,2,3,4,5
//改了下console.log,使得傳入的參數i能夠傳進

//瞬間輸出
for (var i=1; i<=5; i++) { 
    setTimeout( (function(i) {
        return function test(a) {
            console.log(a);
        }(i);//注意這裏
    })(i), i*1000 );
}//結果1,2,3,4,5

**總結:function()這纔是函數的執行,function(x){}(2)這才能把2傳入函數,function(){}(2)不能傳入。**

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章