JS 函数的执行时机

87 阅读1分钟

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)
    })
}