JS 函数的执行时机

308 阅读1分钟

JS 函数的执行时机对 JS 函数执行的结果影响很大。

如下面的代码会打印出6个6

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

而下面的代码会打印出0、1、2、3、4、5

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

Note: setTimeout() 会过一段时间在执行。指定的时间(或延迟)不能保证在指定的确切时间之后执行,而是最短的延迟执行时间。
setTimeout(fn, 0) 将在堆栈为空时立即执行,而不是立即执行。

上面两个例子中,每次执行循环体时,都会需要在堆栈为空时打印出 i 的值。

例1中 i 是全局变量,作用域是整个代码,在循环执行过程中 i 一直在变化,循环执行完毕时,i 的值为6,此时执行6次 console.log(i) 打印出6个6。

例2中 forlet 联用,每轮循环都会创建一个新的局部变量 i,它的作用域只在当轮循环之中,每次循环中的 i 是不同的,即每次要打印的 i 的值也是不同的,所以最后就会打印出0、1、2、3、4、5。

也有其他方法可以的到和例2一样的效果,如

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

每次循环都会调用 fn,每次传入的 i 都只保存在当轮循环的 fn 中。由于每次传入的 i 的值都不一样,所以每次打出的结果也不会相同。