《JS 函数的执行时机》

130 阅读2分钟

执行行如下代码段1

声明一个i变量,执行for循环,而在setTimeout()函数里面,为什么打印结果是6个6?

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

setTimeout()函数是用来指定某个函数或者某段代码,在多少毫秒之后执行。(最快执行时间是4毫秒)
setTimeout指定的代码必须等到本次执行的所有代码都执行完,才会执行。 i是全局变量,而setTimeout函数要等for循环全部执行完之后,此时i已经是6,再执行setTimeout()函数里面的代码,故打印输出6个6。

执行行如下代码段2

执行for循环,而在setTimeout()函数里面,为什么打印结果不是是6个6?而是0 1 2 3 4 5

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

首先 i是在for循环里面声明,是一个局部变量,let声明的i只在for循环有效。每次循环的i都是新变量。 如果每次循环的i都是重新定义变量,那怎么确定本轮i是上一轮的i。因为jS引擎现在能记住每次上一轮的值,初始化本轮变量i时,就在上一轮的值上计算。故而,就算for循环与setTimeout()执行的顺序不变,但打印出来的还是本次循环的值。

除了使用 for let 配合,还有什么其他方法可以打印出 0、1、2、3、4

在 ES6 之前,还有另外的两种方法,一种是利用 setTimeout 的第三个参数,另外一种是利用闭包:

  • 第一种:
for(var i = 0; i<6; i++){
  setTimeout(function(i){
      console.log(i)
  },0,i)
}

第二种:

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

参考链接JS 函数的执行时机(for,let和setTimeout()的结合使用)_徒手敲代码的博客-CSDN博客_for let settimeout