L’hoisting delle variabili let in JavaScript

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).

    console.log(myVar); // => ReferenceError: myVar is not defined
    let myVar;

Una variabile let non può essere letta finché non si passa la linea di codice in cui viene effettivamente definita.

    let myVar;
    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:

    let myVar = 1;
    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).

    let myLet = 1;
    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:

    var myVar = true;
    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:

    var myVar = true;
    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:

    var myVar = true;
    function myFunction() {
        if (!myVar) {
            let myVar = 10;
        }
        console.log(myVar); // => true
    }
    myFunction();

Indice:

Pubblicato in Front-end, JavaScript Taggato con: , ,

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*