經典面試題,循環中使用閉包解決 var 定義函數的問題
for ( var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
複製代碼
首先由於 setTimeout 是個異步函數,全部會先把循環所有執行完畢,這時候 i就是 6 了,因此會輸出一堆 6。
解決辦法有三種,第一種使用閉包
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function timer() {
console.log(j);
}, j * 1000);})(i);}
複製代碼
第二種就是使用 setTimeout 的第三個參數
for ( var i=1; i<=5; i++) {
setTimeout( function timer(j) {
console.log( j );
}, i*1000, i);}
複製代碼
第三種就是使用 let 定義 i 了
for ( let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );}
複製代碼
由於對於 let 來講,他會建立一個塊級做用域,至關於
{ // 造成塊級做用域
let i = 0
{let ii = isetTimeout( function timer() {
console.log( i );
},i*1000 );
}
i++
{let ii = i}
i++
{let ii = i}
...
}
複製代碼