Le variabili let non sfruttano l’hoisting e non possono essere lette prima della loro dichiarazione per la temporal dead zone
In JavaScript, le variabili let sono dichiarate in cima al blocco di istruzioni di cui fanno parte. Accedere prematuramente alle variabili let genera un errore (e non un undefined come accade con le variabili definite con var) in quanto si trovano nella temporal dead zone e non possono ancora essere utilizzare (vedi: Il ciclo di vita di let, const e class in JavaScript).
let myVar;
Una variabile let non può essere letta finché non si passa la linea di codice in cui viene effettivamente definita.
console.log(myVar);// => undefined
Ci si potrebbe chiedere se l’hoisting è veramente applicato alle variabili let o semplicemente prima del suo utilizzo la variabile non venga definita affatto. Vediamo un esempio:
if(true) {
console.log(myVar); // => ReferenceError: myVar is not defined
let myVar = 2;
console.log(myVar); // => 2
}
console.log(myVar); // => 1
Come è possibile notare, se alla variabile myVar all’interno del blocco if non venisse all’applicato l’hoisting dovrebbe essere accessibile il valore definito all’esterno del blocco stesso (quindi stampare 1). In questo caso però, è stato effettuato l’hoisting, la variabile definita con let copre il valore di myVar esterno, e la variabile non è accessibile nella temporal dead zone. La variabile sarà accessibile solo dopo la fase di inizializzazione (let myVar) nel blocco if.
Generare errori quando si tenta di accedere ad una variabile nella temporal dead zone obbliga a seguire delle ottime linee guida di programmazione: prima dichiara e poi usa. Questa linea guida, insieme alle restrizioni di let ai blocchi di istruzioni di cui fanno parte, consentono di scrivere un buon flusso di codice e di applicare l’incapsulamento al codice JavaScript (let consente di proteggere il valore delle variabili dello scope da eventuali modifiche esterne).
var myVar = 2;
if(true) {
let myLet = 11;
var myVar = 22;
console.log(myLet); // => 11
console.log(myVar); // => 22
}
console.log(myLet); // => 1
console.log(myVar); // => 22
Nell’esempio è possibile notare come il valore di let viene preservato una volta usciti dalla blocco di codice e contiene ancora il valore iniziale (1), mentre con var il valore (pur ridefinendo la funzione con myVar nel blocco if) viene alterato.
Un altro esempio in cui è possibile comprendere l’utilità di let è dato dal seguente esempio:
function myFunction() {
if (!myVar) {
var myVar = 10;
}
console.log(myVar);
}
myFunction();
Usando var all’interno della funzione viene applicato l’hoisting e il codice è equivalente a:
function myFunction() {
var myVar;
if (!myVar) { // myVar è undefined
myVar = false;
}
console.log(myVar); // => false
}
myFunction();
Dato che myVar nella condizione dell’if è undefined, si entrerà nell’if e verrà stampato false generando non poca confusione. Utilizzando let, il campo su cui si applica è dato dal solo blocco if e verrà stampato true:
function myFunction() {
if (!myVar) {
let myVar = 10;
}
console.log(myVar); // => true
}
myFunction();
Indice:
- L’hoisting in JavaScript
- L’hoisting delle variabili var in JavaScript
- L’hoisting delle funzioni in JavaScript
- L’hoisting delle variabili let in JavaScript
- L’hoisting delle costanti in JavaScript
- L’hoisting delle classi in JavaScript
Lascia un commento