JS函数的执行机制

128 阅读1分钟

s函数的执行机制,先来看看下面这一段代码:

let i = 0
for( i = 0; i < 6; i++){
    setTimeout(() => {
        console.log(i)
},0)
}
//结果打印出6个6复制代码

这段代码的打印结果是6个6而不是0,1,2,3,4,5。

先来解释为什么是6:

原因是setTimeout的调用时机是在for循环结束之后执行的(其实是和js的异步执行有关,setTimeout放在队列里,当for循环执行结束之后,此时的i已经变成了6(为什么不是5?原因是i = 5的时候会再进行一次i++,此时i = 6;但是这个i没有进入循环,而i的值此时确实已经变成了6),在setTimeout执行的时候将i的值打印出来。

为什么是6个?

原因是for循环执行了 0,1,2,3,4,5六次,里面的setTimeout被定义了6个(可以想象成设定了6个闹钟),所以会打印出6个。

那么如何利用上述方法打印出0,1,2,3,4,5
for(let i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

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

其他方法实现打印出0、1、2、3、4、5

1、闭包

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

2、利用 setTimeout 的第三个参数,将i传进去

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

3、const关键字

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