JS 函数的执行时机(setTimeout)

169 阅读2分钟

JS 函数的执行规则

规则:同步优先、异步靠边、回调垫底。

  • js的执行机制: js是单线程环境,从上到下、依次执行,即同步执行;for循环是同步代码setTimeout是异步代码。js在执行代码的过程中,碰到同步代码会依次执行,碰到异步代码就会将其放入任务队列中进行等待,当同步代码执行完毕后再开始执行异步代码,即异步执行

实例一:let在for循环的外部

let i 
for(i = 0; i<6; i++){
 setTimeout(()=>{   
 console.log(i)   
},0)
 }
 结果是打印出 666666

实例二:将var声明在for内

for(var i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
} 
结果是打印出 666666

打印输出6个6的原因:当同步代码(也就是for循环)执行完毕后,才会开始执行异步的setTimeout代码,因为执行setTimeout时需要从当前作用域内寻找一个变量i,此时for循环已执行完毕,得到当前 i=6,所以执行setTimeout时输出为6,任务队列中的剩余5个setTimeout也依次执行,输出为6。

实例三:将let声明在for内

for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
} 
结果是打印出 012345

打印输出0~5的原因

  • let会单独创建一个作用域
  • 即每次执行时都是一个独立的函数,执行当前代码循环时,setTimeout也作用于当前let,相当于有6个不同的i 相当于
(let i = 0) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 1) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 2) {
    setTimeout(()=>{
        console.log(i)
    },0)
};
(let i = 3) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 4) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 5) {
    setTimeout(()=>{
        console.log(i)
    },0)
};

打印出1~5的其他方法

  1. 闭包
let i 
for(i = 0; i<6; i++){
  !function(j){
      setTimeout(()=>{
        console.log(j)
      },0)
  }(i)
}
  1. 利用 setTimeout 的第三个参数,将i传进去
let i
for(i = 0; i<6; i++){
    setTimeout((value)=>{
      console.log(value)
    },0,i)
}
  1. 利用 const 关键字
let i
for(i=0; i<6; i++)
{
const x=i
setTimeout(()=>{
console.log(x)    
})
}