《JS 函数的执行时机》

104 阅读2分钟

为什么以下代码会打印 6 个 6

image.png

当代码执行到setTimeout,setTimeout是一个定时器它会告诉计算机我会尽快执行,具体的时间不确定,也可以认为是在你for循环完毕我在执行,而在for循环执行完毕时此时的i=6然后再执行setTimeout后的代码,由于for循环了6次,也就是说定时器会执行6次,此时i=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是不会变化的,所以输出的就是正常的。

  • JS函数的调用时机不同,得到的结果不同。

  • setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。意思就是尽快,而不是马上。

  • 如何理解异步呢?异步代码不等待结果,直接进行下面的代码,所以定时器只是开启了,而没有立即执行里面的代码,等到当前运行坏境的代码执行完之后再回来执行定时器里面的代码。

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

此处通过用立即执行创造了n个不同的函数作用域,给setTimeout传入了n个不同的参数,所以就可以打印出0、1、2、3、4、5

let output = function(i) {
  setTimeout(function() {
    console.log(i);
  }, 0);
};
let i
for (i = 0; i < 6; i++) {
  output.call(undefined, i);//从这里传过去的i值被复制,而不是引用
}

原理遇上方相似,也是创造了n个不同的函数作用域,给setTimeout传入了n个不同的参数