一. 解释为什么如下代码会打印 6 个 6
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
答:
setTimeout的意思是马上做,是针对未来说的,马上做不等于现在做。
所以,这串代码会先执行for循环里i,循环6次后结束,然后执行(这时候i已经循环完了) console.log(i)6次,这时候i的值是6,console.log(i)就打印出来6个6。
下面是网友总结的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
- 结束 现在可以看出,由于setTimeout()的执行时间为for语句执行后,所以每次打印出的结果都为6
二. 写出让上面代码打印 0、1、2、3、4、5 的方法
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
// 0 1 2 3 4 5
解释:
通过改变let i =0位置就发生了改变。因为let变量的作用域只能在当前函数中,所以每次for循环生成的都是一个新的i, setTimeout里输出的i就是这个新的i,这个i是不会变化的,所以输出的就是正常的。
三. 其他方法打印出 0、1、2、3、4、5
- 闭包
这里加了一个函数外面的变量j
let i = 0
for(i = 0; i<6; i++){
!function(j){
setTimeout(()=>{
console.log(j)
},0)
}(i)
}
- 利用 setTimeout 的第三个参数
for (var i=0; i<6; ++i) {
setTimeout(function(i){
console.log(i)
}, 0, i)
}