為什么以下代碼會打印出6個6嘲叔,而不是012345呢亡呵?
let i = 0
for(i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
原因:
setTimeout
是用于延遲執(zhí)行代碼的函數(shù),它會把要執(zhí)行的函數(shù)放到 Event Loop 的最后面去硫戈,而當前循環(huán)體又在setTimeout
前面锰什,因此上面的代碼相當于:
let i = 0;
i++;
i++;
i++;
i++;
i++;
i++;
console.log(i)
console.log(i)
console.log(i)
console.log(i)
console.log(i)
console.log(i)
因此會打印出6個6。
而使用 let
配合 for
循環(huán)就可以避免這個問題了:
for(let i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
// 0,1,2,3,4,5
使用閉包和立即執(zhí)行函數(shù)也可以實現(xiàn):
for(var i = 0; i < 6; i++) {
setTimeout(
(function(){
var n = i;
return function() {console.log(n)}
})()
)
}
給setTimeout
傳入一個立即執(zhí)行函數(shù)丁逝,立即執(zhí)行函數(shù)會馬上求值而不是等到Event Loop的最后汁胆,利用這個機會,把當前循環(huán)內(nèi)的i
記錄在函數(shù)體內(nèi)霜幼,和return的函數(shù)形成閉包嫩码,也就能打印出i
傳入時的值了。