題:修改下面的代碼,讓循環輸出的結果依次爲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)不能傳入。**