JS 函数的执行时机

56 阅读1分钟
代码执行结果为六个6
let i = 0;
for(i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i);
  },0)
}

先给定一个全局变量i=0,然后进入for循环,进入setTimeout()定时器时,会设定为尽快执行,可以理解为先把setTimeout()外面的for循环执行结束再进行setTimeout()定时器内的命令。所以for循环执行完毕,此时再执行setTimeout()命令,它去找变量i,此时已经得到了六个i=6,然后这六个6再进入setTimeout()定时器,执行打印命令。最后输出六个6。

代码执行结果为0、1、2、3、4、5
for(let i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

只需要将let i = 0放入for循环中,这次i只会在for循环的作用域里面执行,且let只能声明一次,且只在本轮循环中生效。所以let与for循环配合,每次循环的i都是一个新的变量,最后for循环结束,也是不同的i进入定时器,最后输出0、1、2、3、4、5。

用其他方法打印出 0、1、2、3、4、5
for(var i = 0;i<6;i++){
    ! function(i){
        setTimeout(()=>{console.log(i)},0)
    }(i); //此函数为立即执行函数,此处的i为局部变量
}

for循环时setTimeout()不是立即执行的,for循环执行完成后再执行setTimeout(),此时i的值早已变成6,所以打印出的是六个6。如果给循环中的setTimeout()创建一个闭包作用域(如果一个函数用到了外部的变量,那么这个函数加这个变量就叫做闭包;多个作用域有同名变量i,向上取最近的作用域),让setTimeout()执行的时候找到的变量i是正确的即可打印出0、1、2、3、4、5。