for(var i = 0; i < 4; i++){
setTimeout(() => {
console.log(i)
}, 0)
}
//打印结果为4次4
原因:
- var不支持块级作用域,此处var i声明变量是全局变量
- setTimeout是异步任务中的宏任务,每次for循环都会放到宏任务队列中等待时机执行
- 同步代码for循环执行完,此时变量 i =4;
- 再执行每个宏任务timeout打印结果均为4
下面是正常打印0,1,2,3的常用解决方式
//方式一
for(let i = 0; i < 4; i++){
setTimeout(() => {
console.log(i)
}, 0)
}
//打印结果:0,1,2,3
// 原理: let支持块级作用域,timeout执行时取值是先从当前作用域查找
//方式二
for(var i = 0; i < 4; i++){
setTimeout((i) => {
console.log(i)
}, 0, i)
}
//打印结果:0,1,2,3
//原理: setTimeout,支持给需要执行的函数传参,
详见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)
}
//打印结果:0,1,2,3
//原理: 立即执行函数,形成函数作用域
网友评论