for循环 !important

110 阅读3分钟

代码如下:

for(var i=1;i<=3;i++){
  setTimeout(function(){
     console.log("i",i)
  },0)
}

最后结果为:4 4 4

为什么: setTimeout为异步 SetTimeout有最小值不会为0 查到的是不少于4毫秒

  for(var i=1;i<=3;i++){
     debugger
     console.log("i",i)
  }
  console.log("varlast",i)

这段代码从断点上面看,当循环到第三次的时候,两个i的值都为3,但是循环都没有结束 图片如下: 这个时候还没有跳出循环 多加了一次循环 当跳出循环的时候 varlast的值为4 i的值为 1 2 3
执行顺序如图: 因为没有setTimeout所以不需要等待--》直接同步执行

回到上面: 为什么结果为444

  for(var i=0;i<=3;i++){
     setTimeout(function(){
       debugger
       console.log("i".i) //三次 4 4 4 
     })
  }
  console.log("varlast",i) // 只有一次 4  最开始直接循环到这里为4

原因:在异步里面var所形成的i只有一个,所有都是一样的i,但是上面说到在最后面的时候又循环了一次,所以是一共循环了四次,这个时候i的值为4(最开始直接循环),但是这个是异步的 当所有的循环完了四次之后,才循环里面的setTimeout,但是setTimeout只循环三次,所以i的值为4 4 4 执行顺序如图:因为有setTimeout 所以需要等待--》异步执行

改变方法: 将var改成let 结果为:1 2 3 代码如下:

  for(let i=1;i<=3;i++){
    setTimeout(function(){
      debugger
      console.log("i",i) // 1 2 3 
    },0)
  }
  console.log("letlast",i)  //报错
  

let为块级作用域 for循环也属于区块 所以let在里面for循环一次就有一个作用域,产生的i的值都不一样,循环一次声明一次,多个值。

但是需要注意一定,人家最开始也是循环letlast的 但是报错了,因为有setTimeout代表异步,需要等待,不能马上执行 但是人家又有作用域的庇护,所以找不到letlast所以报错,而且 “let在里面for循环一次就有一个作用域,产生的i的值都不一样,循环一次声明一次,多个值。”,所以值为1 2 3 执行顺序为:

for(let i=1;i<=3;i++){
  debugger
  console.log("i",i)
}
console.log("letlast",i)

执行顺序如图:

因为没有setTimeout所以不是异步,不需要等待,直接同步执行代码,所以得到的结果为1 2 3 最下面报错是因为Let块级作用域,人家找不到letlast!

for循环执行步骤

for(var i=0;i<3;i++){
  console.log("i",i)  0 1 2   //循环体
}
console.log("last",i) 3
1. 设定i的初始值为0
2. 执行0<3 执行console.log("i",i) 0
3. 执行完毕后,执行i++ i这个时候等于1
4. 执行判断条件i<3:1<3 为true 执行console.log("i",i) 1
5. 执行完毕之后,执行i++ i这个时候等于2
6. 执行判断条件i<3:2<3 为true 执行console.log("i",i) 2
7. 执行完毕之后 执行i++ i这个时候等于3
8.执行判断条件 i<3:3<3 为false 不执行
9.不执行 循环体结果为0 1 2 last结果为3