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

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

举个例子,当小明打游戏时,他妈叫他吃饭,这时候他先答应他妈马上去吃饭,接着又继续打一会直到游戏结束再去吃。这里的马上去就相当于 setTimeout 函数的机制,吃饭就是 console.log(i) ,但实际上小明还是先完成了当前手头上的事情(即整个for循环)之后,再尽快去吃饭。不过为什么会这样呢?这跟 JS 函数的执行机制有关, 要知道 setTimeout 是一个异步的函数,那么这段代码的执行就变成了,先走完整个循环,这时 i 已经变成了 6,才开始执行 6 个 console.log(i),所以最终只会打印出 6 个 6。

写出让上面代码打印 0、1、2、3、4、5 的方法

那有没有什么办法能够解决这个问题, 我就想这样,然后还要打印出 0 1 2 3 4 5 。
回答是有的,只需要稍稍改变一下就可以了。
只要把 let i = 0 放进 for 里面就可以实现了。这是JS为了迎合新手玩家而发明的方法。

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

那对上面的代码要怎么给出一个合理的解释呢
因为在 for 循环里用 let 声明 i 的话,每次执行 for 循环,其实都会创建一个新的 i,这个 i 会保留当前 i 的值,所以不管你过多久打印 i,当时的 i 已经被保存了下来,所以会依次打印出 0,1,2,3,4,5

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

  1. var arr = [];
  2. var outNum = (i) => new Promise(res => {
  3. setTimeout(()=>{
  4. console.log(i);
  5. }, 0)
  6. })
  7. for (i=0;i<=5;i++) {
  8. arr.push(outNum(i));
  9. }