妈,我先打完游戏再吃饭
let i
for( i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
i 的结果为???
若答案是0,1,2,3,4,5
完美错过正确答案
正确答案 666666
解释:此时i为全局变量 需等主线程同步任务i全部执行完,再执行之前的setTimeout()
for循环执行步骤:
- i赋值为0
- 判断i < 6 ?,满足进入第一循环
- setTimeout()会过一会执行–>跳过setTimeout()继续执行
- 执行i++,此时i的值为1
- 判断i < 6 ?,满足进入第二循环
- setTimeout()会过一会执行–>跳过setTimeout()继续执行
- 执行i++,此时i的值为2
- 省略…
- 执行i++,此时i的值为6
- 判断i < 6 ?,不满足跳出循环
- 执行第一次循环的setTimeout() //打印出a
- 执行第二次循环的setTimeout() //打印出a
- 执行第三次循环的setTimeout() //打印出a
- 执行第四次循环的setTimeout() //打印出a
- 执行第五次循环的setTimeout() //打印出a
- 执行第六次循环的setTimeout() //打印出a
- 结束
若想要打印0、1、2、3、4、5
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
// 0 1 2 3 4 5
解释:因为在for语句里用let声明变量是局部变量遵循块作用域,所以每次for循环执行时都会生成一个单独的作用域,也会生成一个新的i,相当于有6个 i。 此时,每次执行setTimeout()时都会打印出对应的i,打印结果就是0、1、2、3、4、5了。
- 闭包
let i
for(i = 0; i<6; i++){
!function(j){
setTimeout(()=>{
console.log(j)
},0)
}(i)
}
- 利用 const 关键字
let i
for(i = 0; i<6; i++){
const x = i
setTimeout(()=>{
console.log(x)
})
}