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:
letles variables ne sont visibles que dans leur bloc englobant le plus proche ( { ... }).
letles 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 !).
letles variables ne peuvent pas être redéclarées par un varou let.
- Les
letvariables globales ne sont pas ajoutées à l' windowobjet global .
letles variables sont faciles à utiliser avec les fermetures (elles ne provoquent pas de conditions de concurrence ).
Les restrictions imposées par letré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 letvariables 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.
varpeut 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 varfor exports peut être supplantée si la exportmigration 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 xse 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 ReferenceErroravant que le code puisse être exécuté car il xest 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 varanalyse et s'exécute sans lever d'exceptions.
3. Pas de redéclaration:
Le code suivant montre qu'une variable déclarée avec letne 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 varne 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 ia à 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 iplace:
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
letest inclus dans le projet de 6e édition et sera très probablement dans la spécification finale.