js的执行时机: js是单线程环境,从上到下、依次执行,即同步执行;例:
代码1:
let i = 0;
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
或代码2:
for(var i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
代码1、2中的for是同步代码,setTimeout是异步代码,js在执行代码的过程中,碰到同步代码会依次执行,碰到异步代码就会将其放入任务队列中进行等待,当同步代码执行完毕后再开始执行异步代码。
当同步代码执行完毕后,开始执行异步的setTimeout代码,执行setTimeout时需要从当前作用域内寻找一个变量i,此时for循环已执行完毕,当前 i=6,所以执行setTimeout时输出为6,任务队列中的剩余5个setTimeout也依次执行,输出为6,最终输出结果为6个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只在代码块内才有效,let只能声明一次。变量i是用let声明的,当前的i只在本轮循环中有效,每次循环的i 其实都是一个新的变量,所以setTimeout定时器里面的i,其实是不同的变量,即最后输出0-5;
除了使用 for let 配合,以下方法也可以打印出 0、1、2、3、4、5:
- 利用 setTimeout 的第三个参数,将i传进去
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)
})
}