Skip to content

循环中的var

js
        for (var i = 0; i < 3; i++) {
            setTimeout(() => {
                console.log(i)
            }, 0);
        }
// 打印结果 3 3 3

image-20240812211530605

在上面代码中,a在预编译阶段就被收集到了Global中,

当for循环执行完毕后,再打印a,值已经变成了3。

事件环:

  1. 同步代码执行完成(主执行栈)
  2. 清空微任务
  3. GUI渲染
  4. 拿出一个宏任务到主执行栈中执行

循环中的let

js
         for (let i = 0; i < 2; i++) {
            setTimeout(() => {
                console.log(i)
            }, 0);
         }
// 打印结果 0 1
  1. let i = 0; 在for语句中创建block作用域,收集i,并初始化为0
  2. i < 2 通过,进入到块作用域
  3. 执行setTimeout,把回调放到宏任务队列, 此时回调与这个块作用域捆绑 (闭包)
  4. i++ i初始化为1
  5. i < 2通过,进入到块作用域
  6. 执行setTimeout,把回调放到宏任务队列, 此时回调与这个块作用域捆绑(闭包)
  7. i++ i初始化为2
  8. i < 2不通过,结束主执行栈中的for循环程序
  9. 一个个拿宏任务到主执行栈中执行。

循环中let另外一种情况

js
          let i = 0;
          for (; i < 2; i++) {
            setTimeout(() => {
                console.log(i)
            })
          }
// 打印结果 2 2

image-20240812212943640

不创建块作用域,在预编译中i被收集到了script(脚本作用域中)

回调不会与作用域进行捆绑,在主执行栈执行完后,i已经变成了2。

在执行宏任务的回调,打印出来的i就都是2。