La différence réside dans la portée des variables déclarées avec chacune.
Dans la pratique, la différence de portée a plusieurs conséquences utiles:
let
les variables ne sont visibles que dans leur bloc englobant le plus proche ( { ... }
).
let
les variables ne sont utilisables que dans les lignes de code qui se produisent après la déclaration de la variable (même si elles sont hissées !).
let
les variables ne peuvent pas être redéclarées par un var
ou let
.
- Les
let
variables globales ne sont pas ajoutées à l' window
objet global .
let
les variables sont faciles à utiliser avec les fermetures (elles ne provoquent pas de conditions de concurrence ).
Les restrictions imposées par let
réduisent la visibilité des variables et augmentent la probabilité que des collisions de noms inattendues soient détectées tôt. Cela facilite le suivi et le raisonnement des variables, y compris leur accessibilité (aidant à récupérer la mémoire inutilisée).
Par conséquent, les let
variables sont moins susceptibles de causer des problèmes lorsqu'elles sont utilisées dans de grands programmes ou lorsque des cadres développés indépendamment sont combinés de manière nouvelle et inattendue.
var
peut toujours être utile si vous êtes sûr de vouloir l'effet de liaison unique lorsque vous utilisez une fermeture dans une boucle (# 5) ou pour déclarer des variables globales visibles de l'extérieur dans votre code (# 4). L'utilisation de var
for exports peut être supplantée si la export
migration hors de l'espace du transpilateur et vers le langage principal.
Exemples
1. Aucune utilisation en dehors du bloc englobant le plus proche:
ce bloc de code générera une erreur de référence car la deuxième utilisation de x
se produit en dehors du bloc où il est déclaré avec let
:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
En revanche, le même exemple avec des var
œuvres.
2. Pas d'utilisation avant la déclaration:
ce bloc de code lancera un ReferenceError
avant que le code puisse être exécuté car il x
est utilisé avant sa déclaration:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
En revanche, le même exemple avec var
analyse et s'exécute sans lever d'exceptions.
3. Pas de redéclaration:
Le code suivant montre qu'une variable déclarée avec let
ne peut pas être redéclarée ultérieurement:
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
4. Mondiaux non attachés à window
:
var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link); // OK
console.log(window.link); // undefined (GOOD!)
console.log(window.button); // OK
5. Utilisation facile avec les fermetures: les
variables déclarées avec var
ne fonctionnent pas bien avec les fermetures à l'intérieur des boucles. Voici une boucle simple qui produit la séquence de valeurs que la variable i
a à différents moments:
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
Plus précisément, cela génère:
i is 0
i is 1
i is 2
i is 3
i is 4
En JavaScript, nous utilisons souvent des variables beaucoup plus tard que lors de leur création. Lorsque nous démontrons cela en retardant la sortie avec une fermeture passée à setTimeout
:
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... la sortie reste inchangée tant que nous respectons let
. En revanche, si nous avions utilisé à la var i
place:
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... la boucle produit cinq fois "i is 5" de façon inattendue:
i is 5
i is 5
i is 5
i is 5
i is 5
let
est inclus dans le projet de 6e édition et sera très probablement dans la spécification finale.