在 JavaScript 中“ let”和“ var”之间是否存在性能差异

这两个关键字在作用域方面的差异已经被 给你彻底讨论过了,但是我想知道两者之间是否存在某种性能差异,如果存在,这种性能差异是否可以忽略不计,或者在什么时候它会变得重要?

26889 次浏览

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>

After testing this in Chrome and Firefox, this shows that let is faster than var, but only when inside a different scope than the main scope of a function. In the main scope, var and let are roughly identical in performance. In IE11 and MS Edge, let and var are roughly equal in performance in both cases.

Press the big blue button to see for yourself in your favourite browser.

Currently let has support from only newer browsers, but older browsers are still being used relatively much, which would be a reason to generally not use it yet. If you want to use it somewhere where older browsers wouldn't function otherwise, there should be no problem with it.

Edit: revamped answer since jsperf is not working (see revision history for old version).

仅供参考: 在 Chromev60之后,没有出现进一步的回归。varlet并驾齐驱,var只以不到1% 的优势获胜。由于提升和重用,现实世界中的场景有时会给 var带来优势,但在这一点上,您是在比较苹果和橙子,因为 let的目的是让您避免这种行为,因为语义是不同的。

基准 . Firefox,IE 和 Edge 就像 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倍的差异。类似的结果在铬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);

我重建了 dchekmarev 的函数,这是我的结果。

在 Windows 10 x64(版本1909)、 XAMPP、 Firefox 84.0.2上进行了测试

以毫秒为单位的时间:

  • 让:
  • 16221614
  • 16281653
  • 1872年1859年
  • 15941631
  • 16141733
  • 1661年1918年
  • 16061584
  • 16981644
  • 1648年1903年
  • 16021743

结果是模棱两可的,但在大多数情况下,Var似乎有点 再快点

function varTime(times)
{
var start = (new Date()).getTime();
var sum = 0;
for (var i = 0; i < times; i++) {
for (var j = 0; j < 1000; j++) {
sum += j;
if (sum > 1000000) { sum = 0; }
}
};
console.log('var:', (new Date()).getTime() - start, ' ms');
return sum;
}


function letTime(times)
{
let start = (new Date()).getTime();
let sum = 0;
for (let i = 0; i < times; i++) {
for (let j = 0; j < 1000; j++) {
sum += j;
if (sum > 1000000) { sum = 0; }
}
};
console.log('let:', (new Date()).getTime() - start, ' ms');
return sum;
}


const times = 1000000;


const bla1 = letTime(times);
const bla2 = varTime(times);