let
Ambito di blocco
Le variabili dichiarate utilizzando la letparola chiave hanno un ambito di blocco, il che significa che sono disponibili solo nel blocco in cui sono state dichiarate.
Al livello superiore (al di fuori di una funzione)
Al livello più alto, le variabili dichiarate usando letnon creano proprietà sull'oggetto globale.
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
All'interno di una funzione
All'interno di una funzione (ma al di fuori di un blocco), letha lo stesso ambito di var.
(() => {
var functionScopedVariable = 42;
let blockScopedVariable = 43;
console.log(functionScopedVariable); // 42
console.log(blockScopedVariable); // 43
})();
console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
All'interno di un blocco
Le variabili dichiarate usando letall'interno di un blocco non sono accessibili al di fuori di quel blocco.
{
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
}
console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
All'interno di un ciclo
Le variabili dichiarate con letin loop possono essere referenziate solo all'interno di quel loop.
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
Passanti con chiusure
Se si utilizza letinvece che varin un ciclo, ad ogni iterazione si ottiene una nuova variabile. Ciò significa che puoi tranquillamente utilizzare una chiusura all'interno di un anello.
// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
Zona morta temporale
A causa della zona morta temporale , letnon è possibile accedere alle variabili dichiarate utilizzando prima di essere dichiarate. Tentare di farlo genera un errore.
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
Nessuna nuova dichiarazione
Non puoi dichiarare la stessa variabile più volte usando let. Inoltre, non è possibile dichiarare una variabile utilizzando letcon lo stesso identificativo di un'altra variabile dichiarata utilizzando var.
var a;
var a; // Works fine.
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
const
constè abbastanza simile a let- è a ambito di blocco e ha TDZ. Vi sono, tuttavia, due cose diverse.
Nessuna riassegnazione
La variabile dichiarata utilizzando constnon può essere riassegnata.
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
Si noti che ciò non significa che il valore sia immutabile. Le sue proprietà possono ancora essere modificate.
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
Se vuoi avere un oggetto immutabile, dovresti usare Object.freeze().
È richiesto l'inizializzatore
È sempre necessario specificare un valore quando si dichiara una variabile utilizzando const.
const a; // SyntaxError: Missing initializer in const declaration
letè incluso nella bozza della sesta edizione e molto probabilmente sarà nella specifica finale.