JavaScript Differenza tra var e let


Esempio

(Nota: tutti gli esempi che usano let sono anche validi per const )

var è disponibile in tutte le versioni di JavaScript, mentre let e const fanno parte di ECMAScript 6 e sono disponibili solo in alcuni browser più recenti .

var è orientato alla funzione contenitore o allo spazio globale, a seconda di quando è dichiarato:

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

Ciò significa che "fugge" if istruzioni e tutti i costrutti di blocchi simili:

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

Per confronto, let è a blocchi:

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"

Nota che i e j sono dichiarati solo nel ciclo for e quindi non sono dichiarati al di fuori di esso.

Ci sono molte altre differenze cruciali:

Dichiarazione globale delle variabili

Nell'ambito superiore (al di fuori di qualsiasi funzione e blocco), le dichiarazioni var inseriscono un elemento nell'oggetto globale. let no:

var x = 4;
let y = 7;

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

Re-Dichiarazione

Dichiarare una variabile due volte usando var non produce un errore (anche se è equivalente a dichiararlo una volta):

var x = 4;
var x = 7;

Con let , questo produce un errore:

let x = 4;
let x = 7;

TypeError: l'identificatore x è già stato dichiarato

Lo stesso vale quando y è dichiarato con var :

var y = 4;
let y = 7;

TypeError: l'identificatore y è già stato dichiarato

Tuttavia, le variabili dichiarate con let possono essere riutilizzate (non dichiarate nuovamente) in un blocco nidificato

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

All'interno del blocco l'esterno i si può accedere, ma se il blocco all'interno ha un let dichiarazione per i , l'esterno i non è possibile accedere e getterò un ReferenceError se utilizzato prima della seconda è dichiarato.

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

ReferenceError: i non è definito

sollevamento

Le variabili dichiarate sia con var con let vengono issate . La differenza è che una variabile dichiarata con var può essere referenziata prima del proprio assegnamento, dal momento che viene automaticamente assegnata (con un valore undefined ), ma let può, in particolare richiede che la variabile venga dichiarata prima di essere invocata:

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;

L'area tra l'inizio di un blocco e una dichiarazione let o const è nota come zona morta temporanea e qualsiasi riferimento alla variabile in quest'area causerà un'eccezione ReferenceError . Ciò accade anche se la variabile viene assegnata prima di essere dichiarata :

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

In modalità non rigida, assegnando un valore a una variabile senza alcuna dichiarazione, dichiara automaticamente la variabile nell'ambito globale . In questo caso, invece di y essere dichiarato automaticamente nel campo di applicazione globale, let le riserve il nome della variabile ( y ) e non consente alcun accesso o cessione a prima riga in cui si è dichiarata / inizializzato.