JS 函数的执行时机

为什么以下代码会打印出6个6,而不是012345呢?
let i = 0
for(i = 0; i < 6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}
原因:

setTimeout是用于延迟执行代码的函数,它会把要执行的函数放到 Event Loop 的最后面去,而当前循环体又在setTimeout前面,因此上面的代码相当于:

let i = 0;
i++;
i++;
i++;
i++;
i++;
i++;
console.log(i)
console.log(i)
console.log(i)
console.log(i)
console.log(i)
console.log(i)

因此会打印出6个6。

而使用 let 配合 for 循环就可以避免这个问题了:

for(let i = 0; i < 6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}
// 0,1,2,3,4,5

使用闭包和立即执行函数也可以实现:

for(var i = 0; i < 6; i++) {
  setTimeout(
    (function(){
      var n = i;
      return function() {console.log(n)}
    })()
  )
}

setTimeout传入一个立即执行函数,立即执行函数会马上求值而不是等到Event Loop的最后,利用这个机会,把当前循环内的i记录在函数体内,和return的函数形成闭包,也就能打印出i传入时的值了。

你可能感兴趣的:(JS 函数的执行时机)