JavaScript for(let..){setTimeout...}

今天在 Segmentfault 看一篇文章。 里边举例了一个经典的面试题,异步、单线程的问题。
我也只是了解,知道执行结果是什么,但并不是门清。
但看到把 var 换成 let 声明之后就是另外一个结果了,就有点懵。
所以准备写一篇笔记梳理一下 块级作用域

首先来看下这道面试题:

1
2
3
4
5
for (var i = 1; i <= 5; i++) {
setTimeout(function test() {
console.log(i) // 依次输出:6 6 6 6 6
}, i * 1000);
}

造成这个现象的原因是等到 setTimeout 异步执行时, i 已经变成 6 了。

如果使用 let 声明就是另外一个结果

1
2
3
4
5
for (let i = 1; i <= 5; i++) {
setTimeout(function test() {
console.log(i) // 依次输出:1 2 3 4 5
}, i * 1000);
}

WHY ?

快速解释:因为 let 是块级作用域,当前的 i 只在本轮循环有效,所以每一次循环的 i 其实都是一个新的变量,所以 setTimeout 每次读的值都是不同的。

那为什么使用 let申明 每一次循环都是一个新的变量 ???

使用 babel 编译成 ES5 版本:

1
2
3
4
5
6
7
8
9
10
11
'use strict'

var _loop = function _loop(i) {
setTimeout(function test() {
console.log(i)
}, i * 1000)
}

for (var i = 1; i <= 5; i++) {
_loop(i)
}

闭包?

– 未完成 –

08-06