本文参考网址
1 解释为什么如下代码会打印 6 个 6
首先我们先在控制台运行下面一段代码
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
setTimeout不会立马执行,尤其是再有耗时代码在前的情况下,这是因为JS是单线程的,有一个事件队列机制,在setTimeout回调时候会因为延迟时间塞入事件队列中,排队执行,因此for循环会先执行,(同步优先于异步优先于回调),所以此时6个setTimeout的回调会同时塞入事件队列,然后在for循环执行结束后执行,setTimeout寻找i的值,此时i是一个全局变量,其值为6,循环6次所以打印出6个6
这种情况也出现在下列代码中,原理一致
for(var i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
2 写出让上面代码打印 0、1、2、3、4、5 的方法
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
这是因为let放在for循环中为代码块的作用域并且在每次循环中都人为的创建了一个保存i的值的变量,相当于下列代码,所以代码结果为0、1、2、3、4、5
for(let i = 0; i<6; i++){
//let i = i
setTimeout(()=>{
console.log(i)
},0)
}
3不用for let 的其他解决方法
for (var i = 0; i < 6; i++) {
(function(i){ //立刻执行函数
setTimeout(function (){
console.log(i);
},0);
})(i);
}
使用立即执行函数,这样console.log(i)中的i保存的是每一次循环生成的立即执行函数中的作用域里的了。