';让';和';var';在JavaScript中

';让';和';var';在JavaScript中,javascript,performance,scope,Javascript,Performance,Scope,这两个关键字在作用域方面的差异已经被彻底讨论过了,但我想知道这两个关键字之间是否存在任何性能差异,如果存在,是否可以忽略,或者在什么情况下会变得显著?在对其进行测试后,我得到了以下结果:jsperf已经下降了一段时间;请参阅下面的替换代码 为了检查这一点,我将使用以下基于的性能测试,这使我编写了此函数: /** *查找给定函数的性能 *函数fn要执行的函数 *int n重复的次数 *返回数组[n次迭代的时间,平均执行频率(每秒执行次数)] */ 函数getPerf(fn,n){ var-t0,

这两个关键字在作用域方面的差异已经被彻底讨论过了,但我想知道这两个关键字之间是否存在任何性能差异,如果存在,是否可以忽略,或者在什么情况下会变得显著?

在对其进行测试后,我得到了以下结果:jsperf已经下降了一段时间;请参阅下面的替换代码

为了检查这一点,我将使用以下基于的性能测试,这使我编写了此函数:

/**
*查找给定函数的性能
*函数fn要执行的函数
*int n重复的次数
*返回数组[n次迭代的时间,平均执行频率(每秒执行次数)]
*/
函数getPerf(fn,n){
var-t0,t1;
t0=性能。现在();
对于(变量i=0;i'
var varperf1=getPerf(函数(i){
如果(真){
var a=i;
}
},重复);
msg+='
var
在if()中,对于'+repeat+'迭代('+varperf1[1]+'每秒),使用'+varperf1[0]+'毫秒。
' //-------范围之外----------- var letperf2=getPerf(函数(i){ 如果(真){} 设a=i; },重复); msg+='
let
if()外部的'+letperf2[0]+'毫秒用于'+repeat+'迭代('+letperf2[1]+'每秒)。
' var varperf2=getPerf(函数(i){ 如果(真){} var a=i; },重复); msg+='
var
if()外部的'+varperf1[0]+'毫秒用于'+repeat+'迭代('+varperf1[1]+'每秒)。
' document.getElementById('out').innerHTML=msg

供参考;在Chrome v60之后,没有出现进一步的倒退
var
let
并驾齐驱,其中
var
仅以不到1%的优势获胜。由于吊装和重复使用,现实世界的场景有时会给
var
带来优势,但在这一点上,您将苹果与橙子进行比较,因为
let
旨在让您避免这种行为,因为语义不同

。Firefox、IE和Edge之类的
很好。

$node——版本
$ 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
v6.0.0 $node >timeit=(times,func)=>{ 让开始=(新日期()).getTime(); for(设i=0;itimeit(1000000,()=>{ 设sum=0;//1000000){sum=0;} } 回报金额; }) 2459

相同的范围(功能),相同的代码,5倍的差异。chrome 49.0.2623.75中的类似结果。

内部循环let速度明显较慢,请参见:

838602 ±0.77% 慢61%

(function() {

  "use strict";
  var a=0;
  for(let i=0;i<100;i++) {
    a+=i;
  }
})();
使用var收益率

0,1,2,3,4,5,6,7,8,9
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);
}
for(变量i=0;i<10;i++){
//捕获“i”的当前状态
//通过调用具有当前值的函数
(职能(一){
setTimeout(函数(){console.log(i);},100*i);
})(i) );
}

另一方面,这比使用letvar要慢得多:声明一个变量,值初始化是可选的。让我们在范围外更快

:声明具有块范围的局部变量。让我们在内部循环中稍微慢一点

例:


//重新制作dchekmarev的函数,以下是我的结果:

//windows 10 x64(版本1909)、XAMPP、Firefox 84.0.2

//以毫秒为单位:

  • 变量:让:
  • 16221614
  • 16281653
  • 1872 1859
  • 15941631
  • 16141733
  • 16611918
  • 16061584
  • 16981644
  • 16481903
  • 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);
函数varTime(次)
{
var start=(新日期()).getTime();
var总和=0;
对于(变量i=0;i<次;i++){
对于(var j=0;j<1000;j++){
总和+=j;
如果(总和>1000000){sum=0;}
}
};
log('var:',(new Date()).getTime()-start,'ms');
回报金额;
}
函数时间(次)
{
让开始=(新日期()).getTime();
设和=0;
for(设i=0;i1000000){sum=0;}
}
};
log('let:',(new Date()).getTime()-start,'ms');
回报金额;
}
常数倍=1000000;
const bla1=letTime(次);
const bla2=varTime(次);

@Nickolai如果这是您要查找的答案,请单击顶部答案内容左侧的略图复选标记,将其标记为已接受。这将向其他人表明这个问题已经得到了回答,如果其他人可能会出现在这个页面上,它也将向他们表明这个答案就是你所寻找的。将其标记为已接受也会给提问者(你)和回答者一些声誉分数,这是一个表示感谢的好姿态。Chrome不支持
let
,在Firefox中,您应该提供type属性
当前版本的Chrome确实支持
let
在严格模式下启用实验JS功能标志(
chrome://flags/#enable-javascript和谐
)。这个测试在Chrome和IE11中运行:IE11(“其他”)似乎能很好地处理
let
。另一方面,铬的速度要慢得多
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);
}
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);
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);