Existe-t-il une différence de performance entre ‘let’ et ‘var’ en JavaScript

La différence entre ces deux mots-clés en termes de scope a déjà été discutée en détail ici , mais je me demandais s’il y avait une différence de performance entre les deux, et si oui, est-elle négligeable ou à quel moment?

Après avoir testé ceci sur http://jsperf.com , j’ai obtenu les résultats suivants: jsperf est en panne depuis un moment; voir le code de remplacement ci-dessous.

Pour vérifier cela, j’utiliserai le test de performance suivant basé sur cette réponse , ce qui m’a amené à écrire cette fonction:

/** * 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; Après Chrome v60, aucune régression supplémentaire n’est apparue. var et let sont au coude à coude, la var ne gagnant que moins de 1%. Les scénarios du monde réel donnent parfois à var un avantage en raison du levage et de la réutilisation, mais à ce stade, vous comparez des pommes à des oranges, comme cela est destiné à vous permettre d’éviter ce comportement car la sémantique est différente.

Repère . Firefox, IE et Edge aiment bien.

Les boucles internes sont beaucoup plus lentes voir: https://jsperf.com/let-vs-var-loop

838,602 ± 0,77% 61% plus lent

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

contre.

2 136 387 ± 1,09% le plus rapide

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

En effet, lors de l'utilisation de let , pour chaque itération de boucle, la variable est définie. Exemple:

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

cède à

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

en utilisant var cède à

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

Si vous voulez avoir le même résultat, mais en utilisant var, vous devez utiliser 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); } 

ce qui en revanche est nettement plus lent que l'utilisation de 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 

Même scope (fonction), même code, 5 fois la différence. Résultats similaires dans le chrome 49.0.2623.75.

J’utilise let quand j’ai besoin de réaffecter une variable. Parce que j’utilise une variable pour représenter une chose, le cas d’utilisation de let tendance à être pour les boucles ou les algorithmes mathématiques.

Je n’utilise pas var dans ES6. Il y a de la valeur dans la scope des blocs pour les boucles, mais je ne peux pas penser à une situation dans laquelle je préférerais le var over let .

const est un signal que l’identifiant ne sera pas réaffecté.

let est un signal que la variable peut être réaffectée, comme un compteur dans une boucle, ou un swap de valeur dans un algorithme. Il signale également que la variable ne sera utilisée que dans le bloc dans lequel elle est définie, ce qui ne correspond pas toujours à la fonction contenant l’intégralité.

var est maintenant le signal le plus faible disponible lorsque vous définissez une variable en JavaScript. La variable peut ou non être réaffectée, et la variable peut ou non être utilisée pour une fonction entière, ou simplement pour un bloc ou une boucle.

Attention : avec let et const dans ES6, il n’est plus sûr de vérifier l’existence d’un identifiant en utilisant typeof :

var : Désactiver une variable, l’initialisation de la valeur est facultative. Let est plus rapide en dehors de la scope.

let : Déclarez un varable local avec la scope du bloc.

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