一、解释为什么如下代码会打印 6 个 6 ?

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

首先setTimeout是先执行完当前所有代码,再执行setTimeout里的内容

()=>{ console.log(i) } 即为定时器到期后需要执行的函数。
这个函数会被加入到执行队列而暂时无法被执行。
即使触发时间为0,函数也会等主程序运行完之后,才会执行。
而等到主程序运行结束,i的值已经被赋为6。

所以,()=>{ console.log(i) }函数运行会打印6。
又因为for循环了6次,每次都会调用setTimeout()设置一个定时器,所以共有6个定时器,所以会打印6个6。

image.png
——————————————————————————————————————————

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

(把let放在for里, let块级作用域)

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

let i 是在for里面,作用域在里面
执行了6次,得到每一次的结果,结果分别是 0、1、2、3、4、5

因为JS在for和let一起用的时候会在每次循环的时候多创建一个i,每次循环都会重新创建一个i

image.png
··················································································

如果用了var则不会
image.png


三、有没有其他方式呢?


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

setTimeout定时器的第三个参数。