(共566篇)
全部分类

jsES5与ES6中的for循环
[ JS基础 ] 

注意:本文中所有案例都直接在 chrome 控制台中运行

在 ES5 中最常见的发生 变量提升的一个场景就是关于 for 循环的,先来看一个例子

1
2
3
4
5
var i = 100;
for (var i = 0; i < 10; i++) {
    console.log(i);
}
console.log(i); // 10

for 循环内的变量发生了变量提升,导致最后在执行过程中把全局中变量 i 的值修改了,所以最后输出 i 的值不是 100,而是 10

如果用 ES6 中的 let 来修改一下代码:

1
2
3
4
5
var i = 100;
for (let i = 0; i < 10; i++) {
    console.log(i);
}
console.log(i); // 100

使用 let 声明的地方拥有了独立的作用域,所以 for 循环执行完毕后,最后输出的 i 值仍然是 100

再看一个例子,注意四个例子中使用 var 和 let 的不同,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
for (var i = 0; i < 10; i++) {
    var i = 100;
    console.log(i); // 输出1次 100
}

for (let i = 0; i < 10; i++) {
    let i = 100;
    console.log(i); // 输出10次 100
}

for (var i = 0; i < 10; i++) {
    let i = 100;
    console.log(i); // 输出10次 100
}

for (let i = 0; i < 10; i++) {
    var i = 100;
    console.log(i);
    // Error Uncaught SyntaxError: Identifier 'i' has already been declared
}

第 1 个循环中,同样受到了变量提升的影响,导致循环体执行了一次就停止了,因为 i 的值被修改成了 100,不满足i<10的条件。

第 2 个循环中,ES6 中循环条件和循环体中都使用了 let,因此分别存在单独的作用域,且互不影响,所以输出 10 次 100

第 3 个循环中,循环体形成了单独的作用域,输出语句并不受循环条件中的 i 影响,所以也可以输出 10 次 100

第 4 个循环中,循环体重使用 var 声明了变量,发生了变量提升,这个变量和循坏条件中的声明处于同一个作用域,因此浏览器就会抛出“变量 i 已经被声明”的错误

随着 ES6 的常态化,不管是为了提高逼格还是提高效率,大多数项目都要求使用 ES6 进行开发,但是最终在浏览器中执行的实际上还是 ES5 的代码,比如下面使用 babel 转换的案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 转换前
for (let i = 0; i < 10; i++) {
    let i = 100;
    console.log(i); // 输出10次 100
}
// 转换后
for (var i = 0; i < 10; i++) {
    var i = 100;
    console.log(i); // 输出1次 100
}

根据编写的 ES6 代码,明显表示我们需要的是连续 10 次输出 100,结果被转换成 ES5 之后,输出一次 100 后就停止循环了,这明显不是我们想要的结果,针对这种问题,有且只有一个建议:

循环体中,尽量不要声明与循环条件中相同的变量名