JavaScript Diferencia entre var y let


Ejemplo

(Nota: todos los ejemplos que usan let también son válidos para const )

var está disponible en todas las versiones de JavaScript, mientras que let y const son parte de ECMAScript 6 y solo están disponibles en algunos navegadores más nuevos .

var está dentro del alcance de la función contenedora o del espacio global, dependiendo de cuándo se declara:

var x = 4; // global scope

function DoThings() {
    var x = 7; // function scope
    console.log(x);
}

console.log(x); // >> 4
DoThings();     // >> 7
console.log(x); // >> 4

Eso significa que se "escapa" if declaraciones y todas las construcciones de bloques similares:

var x = 4;
if (true) {
    var x = 7;
}
console.log(x); // >> 7

for (var i = 0; i < 4; i++) {
    var j = 10;
}
console.log(i); // >> 4
console.log(j); // >> 10

En comparación, let ámbito del bloque:

let x = 4;

if (true) {
    let x = 7;
    console.log(x); // >> 7
}

console.log(x); // >> 4

for (let i = 0; i < 4; i++) {
    let j = 10;
}
console.log(i); // >> "ReferenceError: i is not defined"
console.log(j); // >> "ReferenceError: j is not defined"

Tenga en cuenta que i y j solo se declaran en el bucle for y, por lo tanto, no se declaran fuera de él.

Hay varias otras diferencias cruciales:

Declaración de variable global

En el ámbito superior (fuera de cualquier función y bloque), las declaraciones var ponen un elemento en el objeto global. no lo let

var x = 4;
let y = 7;

console.log(this.x); // >> 4
console.log(this.y); // >> undefined

Re-declaración

Declarar una variable dos veces usando var no produce un error (aunque es equivalente a declararlo una vez):

var x = 4;
var x = 7;

Con let , esto produce un error:

let x = 4;
let x = 7;

TypeError: el identificador x ya ha sido declarado

Lo mismo es cierto cuando y se declara con var :

var y = 4;
let y = 7;

TypeError: el identificador y ya ha sido declarado

Sin embargo, las variables declaradas con let se pueden reutilizar (no volver a declarar) en un bloque anidado

let i = 5;    
{
   let i = 6;
   console.log(i); // >> 6
}
console.log(i); // >> 5

Dentro del bloque se puede acceder a la i externa, pero si el bloque interior tiene una declaración de let para i , no se puede acceder a la i externa y lanzará un ReferenceError si se usa antes de que se declare la segunda.

let i = 5;
{
    i = 6;  // outer i is unavailable within the Temporal Dead Zone
    let i;
}

Error de referencia: no está definido

Levantamiento

Variables declaradas ambas con var y let son izadas . La diferencia es que se puede hacer referencia a una variable declarada con var antes de su propia asignación, ya que se asigna automáticamente (con undefined como su valor), pero let puede: requiere específicamente que se declare la variable antes de ser invocada:

console.log(x); // >> undefined
console.log(y); // >> "ReferenceError: `y` is not defined"
//OR >> "ReferenceError: can't access lexical declaration `y` before initialization"
var x = 4;
let y = 7;

El área entre el inicio de un bloque y una declaración let o const se conoce como la Zona Muerta Temporal , y cualquier referencia a la variable en esta área causará un ReferenceError . Esto sucede incluso si la variable se asigna antes de ser declarada :

y=7; // >> "ReferenceError: `y` is not defined"
let y;

En el modo no estricto, al asignar un valor a una variable sin ninguna declaración, se declara automáticamente la variable en el ámbito global . En este caso, en lugar de que y se declare automáticamente en el alcance global, let reserve el nombre de la variable ( y ) y no permita ningún acceso o asignación a ella antes de la línea donde se declara / inicializa.