for(var i = 0; i < 4; i++){
setTimeout(() => {
console.log(i)
}, 0)
}
//打印結(jié)果為4次4
原因:
- var不支持塊級作用域,此處var i聲明變量是全局變量
- setTimeout是異步任務(wù)中的宏任務(wù)新翎,每次for循環(huán)都會放到宏任務(wù)隊列中等待時機執(zhí)行
- 同步代碼for循環(huán)執(zhí)行完程帕,此時變量 i =4;
- 再執(zhí)行每個宏任務(wù)timeout打印結(jié)果均為4
下面是正常打印0,1,2,3的常用解決方式
//方式一
for(let i = 0; i < 4; i++){
setTimeout(() => {
console.log(i)
}, 0)
}
//打印結(jié)果:0,1,2,3
// 原理: let支持塊級作用域料祠,timeout執(zhí)行時取值是先從當前作用域查找
//方式二
for(var i = 0; i < 4; i++){
setTimeout((i) => {
console.log(i)
}, 0, i)
}
//打印結(jié)果:0,1,2,3
//原理: setTimeout骆捧,支持給需要執(zhí)行的函數(shù)傳參,
詳見MDN https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
//方式三
for (var i = 0; i < 4; i++) {
(function (i) {
setTimeout(() => {
console.log(i)
}, 0)
})(i)
}
//打印結(jié)果:0,1,2,3
//原理: 立即執(zhí)行函數(shù)髓绽,形成函數(shù)作用域