for(var i=1;i<=3;i++){
setTimeout(function(){
console.log(i);
},1000);
};
//打印结果:4 4 4
首先我们要知道为什么打印的是4,是因为setTimeout是属于宏任务,那我们了解以下知识点:
在 JavaScript 中,任务可以分为宏任务、微任务和同步任务。它们有不同的执行顺序和特性。以下是对这三种任务的详细解释及分类:
宏任务:包括整体代码、setTimeout
、setInterval
、I/O 操作、UI 渲染等。
微任务:包括 Promise 的 then
和 catch
、MutationObserver
、process.nextTick()
等。
同步任务:包括所有直接在代码中执行的任务
事件循环的执行顺序如下:
- 执行同步任务。
- 当前同步任务执行完成后,执行所有的微任务(直到微任务队列为空)。
- 从宏任务队列中取出下一个宏任务,回到步骤1,重复该过程。
了解完毕我们就应该知道setTimeout是属于宏任务,他要等同步任务先执行,当i等于4的时候,将不符合条件不再执行,这时候同步任务执行完毕,开始执行宏任务这个时候的i已经变成了4,所以打印的3次都为4
解决办法就是:
for(var i=1;i<=3;i++){
setTimeout((function(){
console.log(i);
})(i),1000);
};
//运行结果 1 2 3
这样的话使用了立即执行函数,i作为参数传递过去,但是这样的话又会导致延迟效果没有了,如果想要延迟效果,有想要结果正确
for (var i = 1; i <= 3; i++) {
setTimeout((function(i){
return function() {
console.log(i);
};
})(i), 1000);
}