La diferencia está en el alcance de las variables declaradas con cada uno.
En la práctica, hay una serie de consecuencias útiles de la diferencia en el alcance:
let
las variables solo son visibles en su bloque de cierre más cercano ( { ... }
).
let
Las variables solo se pueden usar en líneas de código que ocurren después de que se declara la variable (¡aunque se hayan izado !).
let
las variables no pueden ser redeclaradas por un posterior var
o let
.
- Las
let
variables globales no se agregan al window
objeto global .
let
Las variables son fáciles de usar con los cierres (no causan condiciones de carrera ).
Las restricciones impuestas por let
reducir la visibilidad de las variables y aumentar la probabilidad de que las colisiones inesperadas de nombres se encuentren temprano. Esto hace que sea más fácil rastrear y razonar sobre las variables, incluida su accesibilidad (lo que ayuda a recuperar la memoria no utilizada).
En consecuencia, let
es menos probable que las variables causen problemas cuando se usan en programas grandes o cuando los marcos desarrollados independientemente se combinan de formas nuevas e inesperadas.
var
aún puede ser útil si está seguro de que desea el efecto de enlace único al usar un cierre en un bucle (# 5) o para declarar variables globales visibles externamente en su código (# 4). El uso de var
para exportaciones puede suplantarse si export
migra fuera del espacio del transpilador al idioma central.
Ejemplos
1. Sin uso fuera del bloque de cierre más cercano:
este bloque de código arrojará un error de referencia porque el segundo uso de x
ocurre fuera del bloque donde se declara con let
:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
En contraste, el mismo ejemplo con var
obras.
2. Sin uso antes de la declaración:
este bloque de código arrojará un ReferenceError
antes de que el código pueda ejecutarse porque x
se usa antes de que se declare:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
Por el contrario, el mismo ejemplo con var
análisis y ejecuciones sin lanzar ninguna excepción.
3. Sin redeclaración:
el siguiente código demuestra que una variable declarada con let
no se puede volver a declarar más tarde:
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
4. Globales no vinculados a 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. Uso fácil con cierres: las
variables declaradas con var
no funcionan bien con cierres dentro de bucles. Aquí hay un bucle simple que genera la secuencia de valores que la variable i
tiene en diferentes momentos:
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
Específicamente, esto produce:
i is 0
i is 1
i is 2
i is 3
i is 4
En JavaScript, a menudo utilizamos variables en un tiempo significativamente más tarde que cuando se crean. Cuando demostramos esto retrasando la salida con un cierre pasado a setTimeout
:
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... la salida permanece sin cambios mientras nos mantengamos let
. Por el contrario, si hubiéramos usado en su var i
lugar:
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... el bucle genera inesperadamente "i is 5" cinco veces:
i is 5
i is 5
i is 5
i is 5
i is 5
let
se incluye en el borrador de la sexta edición y probablemente estará en la especificación final.