JS 函数的执行时机

134 阅读2分钟

当我们学了for循环的时候,肯定会看到如下代码:

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

这时浏览器会打印

0、1、2、3、4、5

这时我们换一种写法,浏览器会打印出6个6,为什么呢?

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

要想理解这段代码之前,我们首先要了解一下setTimeout

JS函数的调用时机不同,得到的结果不同。setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式;其意思就是尽快,而不是马上。

这时我们解释一下为什么会出现6个6

因为setTimeout是一个异步任务,执行到这里的操作会被浏览器丢到**另一个任务队列**里去, 浏览器这时候会继续执行for循环。每一次for循环的时候,setTimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里面,等待执行,for循环了6次,就放了6次,当**主线程**执行完成后,才进入**任务队列**里面执行。这时候因为for循环i=6了,所以输出的全部都是6。

虽然他后面时间的间隔是零,但是他是一个异步函数调用,无论他后面跟的时间是多少,我们都可以理解成“等一会”,“等一会”是什么意思呢,举个例子:你现在刚开了一局王者排位,这时候你妈叫你吃饭,你会说“等一会”,这时你的等一会什么意思呢?就是我先打完这把排位,再去吃饭。

除了for和let配合,我们还有什么方法打印出

0、1、2、3、4、5

1.立即执行函数

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

把setTimeout放在提个立即执行函数里面,每次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)
    })
}