JS 函数的执行时机

179 阅读1分钟

首先来看一段代码

let i = 0
for(i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

你认为结果是什么?

0、1、2、3、4、5吗?

实际执行

实际上是6个6。

因为这里使用了setTimeout(),setTimeout是一个异步任务,执行到这里的操作会被浏览器丢到另一个任务队列里去,浏览器这时候会继续执行for循环。每一次for循环的时候,setTimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里面,等待执行,for循环了6次,就放了6次,当主线程执行完成后,才进入任务队列里面执行。这时候因为for循环i=6了,所以输出的全部都是6。

那可以让上面的代码打印出0、1、2、3、4、5吗?

把let加入到for循环里面

for(let i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

因为let变量的作用域只能在当前函数中,所以每次for循环生成的都是一个新的i, setTimeout里输出的i就是这个新的i,这个i是不会变化的,所以输出的就是正常的。

除了使用 for let 配合,还有什么其他方法可以打印出 0、1、2、3、4、5?

采用闭包

let i
for(i = 0; i<6; i++){
  !function(j){
      setTimeout(()=>{
        console.log(j)
      },0)
  }(i)
}