我注意到在另一个问题中,在循环中使用
原始问题的正确答案是,在for循环中使用
请注意,下面所有的javascript代码都涉及NodeJS版本7.9.0 常规代码:
为了避免在每次循环中都声明额外的
我们可以看到,不仅
因此,在暂时性死区中运行代码,即使未引用未初始化的变量,速度也会慢得多....
最后,为了展示差异,我们将
现在,
有人知道我关于暂时性死区性能的假设是否正确,或者提供一个不同的解释吗?
let
和var
变量声明会有性能差异。原始问题的正确答案是,在for循环中使用
let
会更慢,因为let
为每次迭代创建一个新作用域来保存let
声明的变量的值。需要进行更多的工作,所以较慢是正常的。仅供参考,我提供了代码和在NodeJS(7.9.0)执行时间中的结果:请注意,下面所有的javascript代码都涉及NodeJS版本7.9.0 常规代码:
'use strict';
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');
console.time('let');
for (let j = 0; j < 100000000; j++) {}
console.timeEnd('let');
输出:
var: 55.792ms
let: 247.123ms
为了避免在每次循环中都声明额外的
j
作用域,我们在循环之前声明j
变量。人们会期望这样做会使let
循环的性能与var
相匹配。但是,结果并不是这样!以下是代码和结果供参考:
在循环之前定义let
的代码:
'use strict';
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');
console.time('let');
let j;
for (j = 0; j < 100000000; j++) {}
console.timeEnd('let');
输出:
var: 231.249ms
let: 233.485ms
我们可以看到,不仅
let
循环没有变得更快,而且var
循环也变得和let
一样慢了!!!唯一的解释是,由于我们不在任何块或函数中,因此两个变量都声明在全局模块作用域中。然而,正如这里所引用的,变量在作用域中间的let
声明会创建一个暂时性死区,这使得变量j
未初始化,而var
则将变量初始化为已定义。因此,在暂时性死区中运行代码,即使未引用未初始化的变量,速度也会慢得多....
最后,为了展示差异,我们将
j
变量声明在程序顶部,以展示在没有暂时性死区的情况下运行它的结果。
没有暂时性死区的代码:
'use strict';
let j;
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');
console.time('let');
for (j = 0; j < 100000000; j++) {}
console.timeEnd('let');
输出:
var: 55.586ms
let: 55.009ms
现在,
let
和 var
循环的性能都得到了类似的优化!有人知道我关于暂时性死区性能的假设是否正确,或者提供一个不同的解释吗?