循环中的var
js
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i)
}, 0);
}
// 打印结果 3 3 3
在上面代码中,a在预编译阶段就被收集到了Global中,
当for循环执行完毕后,再打印a,值已经变成了3。
事件环:
- 同步代码执行完成(主执行栈)
- 清空微任务
- GUI渲染
- 拿出一个宏任务到主执行栈中执行
循环中的let
js
for (let i = 0; i < 2; i++) {
setTimeout(() => {
console.log(i)
}, 0);
}
// 打印结果 0 1
- let i = 0; 在for语句中创建block作用域,收集i,并初始化为0
- i < 2 通过,进入到块作用域
- 执行setTimeout,把回调放到宏任务队列, 此时回调与这个块作用域捆绑 (闭包)
- i++ i初始化为1
- i < 2通过,进入到块作用域
- 执行setTimeout,把回调放到宏任务队列, 此时回调与这个块作用域捆绑(闭包)
- i++ i初始化为2
- i < 2不通过,结束主执行栈中的for循环程序
- 一个个拿宏任务到主执行栈中执行。
循环中let另外一种情况
js
let i = 0;
for (; i < 2; i++) {
setTimeout(() => {
console.log(i)
})
}
// 打印结果 2 2
不创建块作用域,在预编译中i被收集到了script(脚本作用域中)
回调不会与作用域进行捆绑,在主执行栈执行完后,i已经变成了2。
在执行宏任务的回调,打印出来的i就都是2。