0

在下面的示例中,为什么 var 比 let in for 循环花费的时间长?我对此进行了一些研究,发现 var 由于功能范围而在全局范围内定义变量,而让在块范围内定义变量。这就是为什么 ' var ' 比 'let' 需要更长的时间,但仍然无法找到关于为什么会这样的实际理解?

console.time('letCounter');
for (let letCounter = 0; letCounter < 10500; letCounter++) {
    console.log('letCounter', letCounter);
}
console.timeEnd('letCounter');
// 598.838134765625ms

console.time('varCounter');
for (var varCounter = 0; varCounter < 10500; varCounter++) {
    console.log('varCounter', varCounter);
}
console.timeEnd('varCounter');
// 656.56494140625ms
4

1 回答 1

1

全局变量的问题是编译器无法知道内容是否将被“外部”函数访问(即在编译时不知道主体)。

例如,如果它是一个全局变量,则console.log可以(理论上)改变。varCounter然后必须将变量存储在完整的 Javascript 插槽中(能够包含字符串、数组、对象),然后从中读取以进行增量。

如果变量是本地变量,则如果未捕获 var,则无法访问,因此可以优化变量本身,并且循环可以检测模式并增加一个 32 位整数作为索引,而不分配完整的 Javascript 插槽.

如果变量是函数局部变量,那么var情况就不同了,因为它也不能被外部函数访问。在这种情况下,如果编译器不够聪明,执行甚至可能var比 with更快:原因是如果在主体中变量可能被闭包捕获,则必须在每次迭代时分配一个新的闭包单元。let这不会发生,var因为范围是整个函数(不是for循环体):

 x = [];
 for (let i=0; i<10; ++) {
     x.push(()=>i);
 }
 console.log(x[4]()); // Shows 4

在上面的循环中更改letvar10,因为所有闭包都在捕获相同的var单元格。

于 2019-07-03T06:29:42.733 回答