废话不说上代码
for(var i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
//执行输出6个6
输出结果跟我们正常来想的不一样是为什么,为什么不是依次输出0-5呢?
这是因为setTimeout()指定的代码,必须等到本次执行的所有代码都执行完,才会执行。也就是说for循环执行完才轮到它
延迟为 0 意味着“马上”执行,或者尽快执行。事实上实际延迟比设定值更久,在浏览器中,setTimeout() 的每调用一次定时器的最小间隔是4ms
而变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i,每一次循环,变量i的值都会发生改变,循环结束执行setTimeout(),此时i的值为6,所以就会打印出6个6
有什么方法可以让代码按正常逻辑运行呢?
方法一:for和let配合使用
for(let i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
//执行输出0,1,2,3,4,5
let声明的变量只在本轮循环有效,所以每一次循环的i其实都是一个新的变量。JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。
方法二:使用setTimeout的第三个参数
for(var i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0,i)
}
//执行输出0,1,2,3,4,5
附加参数,一旦定时器到期,它们就会作为参数传递给function
方法三:使用闭包
for(var i=0;i<6;i++){
(function(i){
setTimeout(()=>{
console.log(i);
}, 0);
})(i)
}