¿Hay una diferencia de rendimiento entre ‘let’ y ‘var’ en JavaScript?

La diferencia entre estas dos palabras clave en términos de scope ya se ha discutido a fondo aquí , pero me preguntaba si hay algún tipo de diferencia de rendimiento entre los dos, y si es así, ¿es insignificante, o en qué punto sería importante?

Después de probar esto en http://jsperf.com , obtuve los siguientes resultados: jsperf ha estado inactivo por un tiempo; ver el código de reemplazo a continuación.

Para verificar esto, utilizaré la siguiente prueba de rendimiento basada en esta respuesta , que me llevó a escribir esta función:

/** * 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 += 'let inside an if() takes ' + letperf1[0] + ' ms for ' + repeat + ' iterations (' + letperf1[1] + ' per sec).
' var varperf1 = getPerf(function(i) { if (true) { var a = i; } }, repeat); msg += 'var inside an if() takes ' + varperf1[0] + ' ms for ' + repeat + ' iterations (' + varperf1[1] + ' per sec).
' //-------outside a scope----------- var letperf2 = getPerf(function(i) { if (true) {} let a = i; }, repeat); msg += 'let outside an if() takes ' + letperf2[0] + ' ms for ' + repeat + ' iterations (' + letperf2[1] + ' per sec).
' var varperf2 = getPerf(function(i) { if (true) {} var a = i; }, repeat); msg += 'var outside an if() takes ' + varperf1[0] + ' ms for ' + repeat + ' iterations (' + varperf1[1] + ' per sec).
' document.getElementById('out').innerHTML = msg
  

FYI; Después de Chrome v60, no han aparecido más regresiones. var y let son cuello y cuello, con var solo ganando en menos del 1%. Los escenarios del mundo real a veces le dan a var una ventaja debido a la elevación y la reutilización, pero en ese momento está comparando manzanas con naranjas, ya let le permite evitar ese comportamiento porque la semántica es diferente.

Benchmark . A Firefox, IE y Edge les parece bien.

Los bucles interiores son significativamente más lentos para ver: https://jsperf.com/let-vs-var-loop

838,602 ± 0,77% 61% más lento

 (function() { "use strict"; var a=0; for(let i=0;i<100;i++) { a+=i; } })(); 

vs.

2,136,387 ± 1,09% más rápido

 (function() { "use strict"; var a=0; for(var i=0;i<100;i++) { a+=i; } })(); 

Esto se debe a que al usar let , para cada iteración de ciclo la variable tiene un scope. ejemplo:

 for (let i = 0; i < 10 ; i++) { setTimeout(function() { console.log(i); }, 100 * i); } 

cede a

 0,1,2,3,4,5,6,7,8,9 

usando rendimientos de var para

 10,10,10,10,10,10,10,10,10,10 

Si quieres tener el mismo resultado, pero usando var tienes que usar un 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); } 

que por otro lado es significativamente más lento que usar 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 

Mismo scope (función), mismo código, 5 veces la diferencia. Resultados similares en cromo 49.0.2623.75.

Uso let cuando necesito reasignar una variable. Como utilizo una variable para representar una cosa, el caso de uso para let tiende a ser para bucles o algoritmos matemáticos.

No uso var en ES6. Hay un valor en el scope del bloque para los bucles, pero no puedo pensar en una situación en la que prefiera var sobre let .

const es una señal de que el identificador no será reasignado.

let , es una señal de que la variable puede reasignarse, como un contador en un bucle, o un intercambio de valores en un algoritmo. También indica que la variable se usará solo en el bloque en el que está definida, que no siempre es la función que lo contiene.

var es ahora la señal más débil disponible cuando defines una variable en JavaScript. La variable puede reasignarse o no, y la variable puede o no ser utilizada para una función completa, o solo para un bloque o bucle.

Advertencia : con let y const en ES6, ya no es seguro verificar la existencia de un identificador usando typeof :

var : Deacleare una variable, inicialización de valor opcional. Let es más rápido en scope externo.

let : Declare un objeto local que se puede usar con el bloque scope.Let es más rápido dentro del scope interno.

Ex:

 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);