JS 函数的执行时机

441 阅读1分钟

为什么如下代码会打印 6 个 6

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

setTimeout(): 设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。所以上面代码的setTimeout()是在最后才执行的。

在for循环时

  1. 先赋值i的值为0
  2. 然后判断是否 i<6 ? 如果满足条件会继续进入下一个循环。
  3. 这时本来要执行setTimeout(),但由于setTimeout()的性质,需要等一会才执行。
  4. 执行i++,此时i赋值为1.
  5. 继续判断i<6,满足进入第二个循环.
  6. ……
  7. 直到i的值是6时,不满足i<6.
  8. 停止循环
  9. 这时,前面的六次循环中的setTimeout() 开始执行,并打印出现在的i。 由于该循坏中,setTimeout()执行了六次并是在最后执行的,而最后的i为6。因此,会打印出 6 个 6。

写出让上面代码打印 0、1、2、3、4、5 的方法

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

  • 因为 JS 在 for 和 let 一起用的时候会加东西
  • 并且每次循环会多创建一个 i

除了使用 for let 配合,打印出 0、1、2、3、4、5的方法

使用立即执行函数

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


还可以使用setTimeout的第三个参数

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

使用const关键字

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

把const改成let也可以