这两个关键字在范围方面的区别已经在这里进行了彻底的讨论,但我想知道两者之间是否存在任何类型的性能差异,如果是,它可以忽略不计,或者在什么时候会变得显着?
JavaScript 中的“let”和“var”之间是否存在性能差异
在http://jsperf.com上测试后,我得到了以下结果:jsperf 宕机有一段时间了;请参阅下面的替换代码。
为了检查这一点,我将根据这个答案使用以下性能测试,这促使我编写了这个函数:
/**
* Finds the performance for a given function
* function fn the function to be executed
* int n the amount of times to repeat
* return array [time for n iterations, average execution frequency (executions per second)]
*/
function getPerf(fn, n) {
var t0, t1;
t0 = performance.now();
for (var i = 0; i < n; i++) {
fn(i)
}
t1 = performance.now();
return [parseFloat((t1 - t0).toFixed(3)), parseFloat((repeat * 1000 / (t1 - t0)).toFixed(3))];
}
var repeat = 100000000;
var msg = '';
//-------inside a scope------------
var letperf1 = getPerf(function(i) {
if (true) {
let a = i;
}
}, repeat);
msg += '<code>let</code> inside an if() takes ' + letperf1[0] + ' ms for ' + repeat + ' iterations (' + letperf1[1] + ' per sec).<br>'
var varperf1 = getPerf(function(i) {
if (true) {
var a = i;
}
}, repeat);
msg += '<code>var</code> inside an if() takes ' + varperf1[0] + ' ms for ' + repeat + ' iterations (' + varperf1[1] + ' per sec).<br>'
//-------outside a scope-----------
var letperf2 = getPerf(function(i) {
if (true) {}
let a = i;
}, repeat);
msg += '<code>let</code> outside an if() takes ' + letperf2[0] + ' ms for ' + repeat + ' iterations (' + letperf2[1] + ' per sec).<br>'
var varperf2 = getPerf(function(i) {
if (true) {}
var a = i;
}, repeat);
msg += '<code>var</code> outside an if() takes ' + varperf1[0] + ' ms for ' + repeat + ' iterations (' + varperf1[1] + ' per sec).<br>'
document.getElementById('out').innerHTML = msg
<output id="out" style="font-family: monospace;white-space: pre-wrap;"></output>
在 Chrome 和 Firefox 中对此进行测试后,这表明它let
比 快var
,但前提是在与函数的主范围不同的范围内。在主要范围内,var
和let
在性能上大致相同。在IE11和MS边缘,let
并且var
在这两种情况下的性能大致相等。
按下蓝色大按钮,在您最喜爱的浏览器中亲自查看。
目前let
已经从只有较新的浏览器的支持,但旧的浏览器仍在使用比较多的,这将是一个理由,一般不使用它。如果您想在旧浏览器无法正常运行的地方使用它,那么它应该没有问题。
编辑:修改后的答案,因为 jsperf 不起作用(请参阅旧版本的修订历史)。
供参考; 在 Chrome v60 之后,没有出现进一步的回归。var
并且let
并驾齐驱,var
只有不到 1% 的胜率。var
由于提升和重用,现实世界的场景有时会带来优势,但此时您将苹果与橙子进行比较,这let
是为了让您避免这种行为,因为语义不同。
基准。Firefox、IE 和 Edge 就好let
了。
内部循环让明显变慢,请参阅:https : //jsperf.com/let-vs-var-loop
838,602 ±0.77% 慢 61%
(function() {
"use strict";
var a=0;
for(let i=0;i<100;i++) {
a+=i;
}
})();
对比
2,136,387 ±1.09% 最快
(function() {
"use strict";
var a=0;
for(var i=0;i<100;i++) {
a+=i;
}
})();
这是因为在使用let 时,对于每次循环迭代,变量都是有作用域的。例子:
for (let i = 0; i < 10 ; i++) {
setTimeout(function() { console.log(i); }, 100 * i);
}
屈服于
0,1,2,3,4,5,6,7,8,9
使用 var 产生
10,10,10,10,10,10,10,10,10,10
如果您想获得相同的结果,但使用var您必须使用 IIFE:
for (var i = 0; i < 10; i++) {
// capture the current state of 'i'
// by invoking a function with its current value
(function(i) {
setTimeout(function() { console.log(i); }, 100 * i);
})(i);
}
另一方面,这比使用let慢得多。
$ node --version
v6.0.0
$ node
> timeit = (times, func) => {
let start = (new Date()).getTime();
for (let i = 0; i < times; i++) {
func();
};
return (new Date()).getTime() - start;
};
[Function]
> timeit(1000000, () => {
let sum = 0; // <-- here's LET
for (let i = 0; i < 1000; i++) {
sum += i;
if (sum > 1000000) { sum = 0; }
}
return sum;
})
12144
> timeit(1000000, () => {
var sum = 0; // <-- here's VAR
for (let i = 0; i < 1000; i++) {
sum += i;
if (sum > 1000000) { sum = 0; }
}
return sum;
})
2459
相同的范围(功能),相同的代码,5 倍的差异。chrome 49.0.2623.75 中的结果类似。
var : 声明一个变量,值初始化可选。让在外部范围更快。
let:声明一个具有块作用域的局部变量。让内部循环有点慢。
前任:
var a;
a = 1;
a = 2; //re-intilize possibe
var a = 3; //re-declare
console.log(a); //3
let b;
b = 5;
b = 6; //re-intilize possibe
// let b = 7; //re-declare not possible
console.log(b);