s函数的执行机制,先来看看下面这一段代码:
let i = 0
for( i = 0; i < 6; i++){
setTimeout(() => {
console.log(i)
},0)
}
//结果打印出6个6复制代码
这段代码的打印结果是6个6而不是0,1,2,3,4,5。
先来解释为什么是6:
原因是setTimeout的调用时机是在for循环结束之后执行的(其实是和js的异步执行有关,setTimeout放在队列里,当for循环执行结束之后,此时的i已经变成了6(为什么不是5?原因是i = 5的时候会再进行一次i++,此时i = 6;但是这个i没有进入循环,而i的值此时确实已经变成了6),在setTimeout执行的时候将i的值打印出来。
为什么是6个?
原因是for循环执行了 0,1,2,3,4,5六次,里面的setTimeout被定义了6个(可以想象成设定了6个闹钟),所以会打印出6个。
那么如何利用上述方法打印出0,1,2,3,4,5
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
因为let变量的作用域只能在当前函数中,所以每次for循环生成的都是一个新的i,setTimeout里输出的i就是这个新的i,这个i是不会变化的,所以输出的就是正常的。
其他方法实现打印出0、1、2、3、4、5
1、闭包
let i
for(i = 0; i<6; i++){
!function(j){
setTimeout(()=>{
console.log(j)
},0)
}(i)
}
2、利用 setTimeout 的第三个参数,将i传进去
let i
for(i = 0; i<6; i++){
setTimeout((value)=>{
console.log(value)
},0,i)
}
3、const关键字
let i
for(i = 0; i<6; i++){
const x = i
setTimeout(()=>{
console.log(x)
})
}