JS 函数的执行时机

112 阅读1分钟

我们先来看一段代码

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

他的输出是什么?

0 1 2 3 4 5吗?不,是 6 6 6 6 6 6

因为循环属于同步操作,会一直执行,而setTimeout属于异步操作

异步操作会等代码运行完,再执行。

所以我们的循环先执行,六次循环之后,i=6

好了,此时代码执行完毕,异步操作setTimeout可以执行里面的代码了。

他的代码是6次的打印i,此时i也等于6,所以打印出来的就是6个6了

那我们如何才能打印出心中的答案 0 1 2 3 4 5呢?

只需要将let写入for循环中就可以了

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

此时,输出就变成了 0 1 2 3 4 5

除了let还有什么办法呢?

利用“闭包” 异步输出 0 1 2 3 4

在setTimeout外部创建一个立即执行的表达式,并将i当作参数传递进闭包

for(var i = 0; i < 5; i++) {
  !function (i) {
    setTimeout(() => {
      console.log(i);  // 0 1 2 3 4
    }, 0)
  }(i)
}