Articolo originale: https://www.freecodecamp.org/news/javascript-temporal-dead-zone-and-hoisting-explained/

Temporal Dead Zone e Hoisting sono due termini essenziali in JavaScript. Ma capire come funzionano può facilmente confonderti se non ti approcci correttamente.

Ma non preoccuparti! Questo articolo è qui per aiutarti a comprendere bene i due termini.

Quindi rilassati, prendi la tua tazza di caffè preferita e iniziamo con la TDZ.

Che cos'è esattamente una zona morta temporale in JavaScript?

Una zona morta temporale (TDZ) è l'area di un blocco in cui una variabile è inaccessibile fino al momento in cui il computer non la inizializza completamente con un valore.

  • Un blocco è una coppia di parentesi graffe ( {...}) utilizzate per raggruppare più istruzioni.
  • L'inizializzazione si verifica quando si assegna un valore iniziale a una variabile.

Si supponga di tentare di accedere a una variabile prima della sua completa inizializzazione. In tal caso, JavaScript genererà un errore ReferenceError.

Quindi, per evitare che JavaScript generi un tale errore, devi ricordarti di accedere alle tue variabili dall'esterno della zona morta temporale.

Ma dove inizia e dove finisce esattamente il TDZ? Scopriamolo subito.

Dov'è esattamente l'ambito di una zona morta temporale?

La zona morta temporale di un blocco inizia all'inizio dell'ambito locale del blocco. Termina quando il computer inizializza completamente la variabile con un valore.

Ecco un esempio:

{
  // La TDZ di bestFood inizia qui (all'inizio dell'ambito locale di questo blocco)
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  console.log(bestFood); // restituisce ReferenceError perché la TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  let bestFood = "Riso saltato con verdure"; // La TDZ di bestFood finisce qui
  // La TDZ di bestFood non esiste qui
  // La TDZ di bestFood non esiste qui
  // La TDZ di bestFood non esiste qui
}

Provalo su StackBlitz

In questo frammento di codice, la TDZ del blocco inizia dalla parentesi graffa di apertura ({) e termina una volta che il computer inizializza bestFood con il valore della stringa "Riso saltato con verdure".

Quando esegui questo codice, vedrai che l'istruzione  console.log() restituirà un ReferenceError.

JavaScript restituirà un ReferenceError perché abbiamo utilizzato l'istruzione console.log() per accedere a bestFood prima della sua completa inizializzazione. In altre parole, abbiamo invocato bestFood all'interno della zona morta temporale.

Tuttavia, ecco come accedere a bestFood con successo dopo la sua completa inizializzazione:

{
  // TDZ inizia qui (all'inizio dell'ambito locale di questo blocco)
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  let bestFood = "Riso saltato con verdure"; // La TDZ di bestFood finisce qui
  console.log(bestFood); // restituisce "Riso saltato con verdure" perché la TDZ di bestFood non esiste qui
  // La TDZ di bestFood non esiste qui
  // La TDZ di bestFood non esiste qui
}

Provalo su StackBlitz

Consideriamo ora questo esempio:

{
  // TDZ inizia qui (all'inizio dell'ambito locale di questo blocco)
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  // La TDZ di bestFood continua qui
  let bestFood; // La TDZ di bestFood finisce qui
  console.log(bestFood); // restituisce undefined perché la TDZ di bestFood non esiste qui
  bestFood = "Riso saltato con verdure"; // la TDZ di bestFood non esiste qui
  console.log(bestFood); // restituisce "Riso saltato con verdure" perché la TDZ di bestFood non esiste qui
}

Provalo su StackBlitz

Puoi vedere che il primo console.log nell'esempio sopra ha restituito undefined.

JavaScript restituisce undefined perché non abbiamo assegnato a bestFood un valore prima di utilizzarlo ( invocandolo ). Per questo motivo, JavaScript lo ha impostato al valore predefinito e cioè appunto undefined.

Tieni presente che devi specificare un valore per una variabile const mentre la dichiari . A parte questa eccezione, tutti gli altri principi della zona morta temporale delle variabili let si applicano anche a const. Tuttavia, var funziona in modo diverso.

In che modo la TDZ di Var differisce dalle variabili Let e ​​Const?

La principale differenza tra la zona morta temporale di una variabile var, let, e const è quando termina la loro TDZ.

Ad esempio, considera questo codice:

{
  // la TDZ di bestFood inizia e finisce qui
  console.log(bestFood); // restituisce undefined perché la TDZ di bestFood non esiste qui
  var bestFood = "Riso saltato con verdure"; // la TDZ di bestFood non esiste qui
  console.log(bestFood); // restituisce "Riso saltato con verdure" perché la TDZ di bestFood non esiste qui
  // la TDZ di bestFood non esiste qui
  // la TDZ di bestFood non esiste qui
}

Provalo su StackBlitz

Quando esegui l'esempio sopra, vedrai che la prima istruzione console.log restituirà undefined.

L'istruzione console.log ha restituito correttamente un valore ( undefined) perché JavaScript assegna automaticamente undefined a una variabile var sollevata (hoisted).

In altre parole, quando il computer solleva una variabile var, la inizializza automaticamente  con il valore undefined.

Al contrario, JavaScript non inizializza una variabile let (o const) con alcun valore ogni volta che la solleva. Quindi, la variabile rimane morta e inaccessibile.

Pertanto, la TDZ di una variabile let (o const) termina quando JavaScript la inizializza completamente con il valore specificato durante la sua dichiarazione.

Mentre, la TDZ di una variabile var termina immediatamente dopo il suo sollevamento, non quando la variabile viene completamente inizializzata con il valore specificato durante la sua dichiarazione.

Ma cosa si intende esattamente per "sollevamento"? Scopriamolo di seguito.

Cosa significa esattamente sollevamento in JavaScript?

Per hoisting si intende che JavaScript dà maggiore precedenza alla dichiarazione di variabili, classi e funzioni durante l'esecuzione di un programma.

Hoisting consiste nell'effettuare il processo delle dichiarazioni del computer prima di qualsiasi altro codice.

Nota: il sollevamento non significa che JavaScript riorganizza o sposta il codice uno sopra l'altro.

Il sollevamento conferisce semplicemente una maggiore specificità alle dichiarazioni JavaScript. Pertanto, fa in modo che il computer legga ed elabori le dichiarazioni prima di analizzare qualsiasi altro codice in un programma.

Ad esempio, considera questo frammento di codice:

{
  // Dichiara una variabile:
  let bestFood = "Pesce e patatine";

  // Dichiara un'altra varaiabile:
  let myBestMeal = function () {
    console.log(bestFood);
    let bestFood = "Riso saltato con verdure";
  };

  // Invoca la funzione myBestMeal:
  myBestMeal();
}

// Il codice di sopra tornerà:
"Uncaught ReferenceError: Cannot access 'bestFood' before initialization"

Provalo su StackBlitz

L'esempio di sopra ha restituito un ReferenceError a causa dell'ordine di precedenza con cui il computer ha eseguito ogni codice.

In altre parole, le dichiarazioni del programma hanno una precedenza maggiore su inizializzazioni, invocazioni e altro codice.

Esaminiamo tramite un tour passo passo come JavaScript ha eseguito il codice di sopra.

Come funziona il sollevamento JavaScript passo dopo passo

Di seguito è riportata una panoramica di come JavaScript ha eseguito il codice precedente.

1. JavaScript ha analizzato la prima dichiarazione bestFood

let bestFood // Questa è la prima dichiarazione bestFood del programma

La prima dichiarazione della variabile bestFood è il primo codice analizzato dal computer.

Si noti che dopo che il computer ha letto la dichiarazione della variabile bestFood, JavaScript ha mantenuto automaticamente la variabile in una zona morta temporale fino a quando non è stata completamente inizializzata.

Pertanto, qualsiasi tentativo di accesso a bestFood prima della sua completa inizializzazione restituirebbe un ReferenceError.

2. Il computer analizza la dichiarazione della variabile myBestMeal

let myBestMeal

La dichiarazione della variabile myBestMeal era il secondo codice JavaScript analizzato.

Immediatamente dopo che il computer ha letto la dichiarazione della variabile myBestMeal, JavaScript ha mantenuto automaticamente la variabile in una zona morta temporale fino a quando non è stata completamente inizializzata.

Pertanto, qualsiasi tentativo di accesso myBestMeal prima della sua completa inizializzazione restituirebbe un ReferenceError.

3. Il computer ha inizializzato la variabile bestFood

bestFood = "Pesce e patatine";

Il terzo passaggio del computer è stato l'inizializzazione di bestFood con la stringa  "Pesce e patatine".

Pertanto, invocare bestFood a questo punto ritornerebbe "Pesce e patatine".

4. JavaScript inizializza la Variabile myBestMeal

myBestMeal = function() {
  console.log(bestFood);
  let bestFood = "Riso saltato con verdure";
};

In quarto luogo, JavaScript inizializza myBestMeal con la funzione specificata. Quindi, se avessi invocato myBestMeal a questo punto, la funzione sarebbe restituita.

5. Il computer ha chiamato la funzione myBestMeal

myBestMeal();

L'invocazione della funzione myBestMeal era la quinta azione del computer.

Dopo l'invocazione, il computer ha elaborato ogni codice nel blocco della funzione. Tuttavia, le dichiarazioni avevano una precedenza maggiore rispetto ad altri codici.

6. JavaScript ha analizzato la dichiarazione della funzione bestFood

let bestFood // Questa è la seconda dichirazione di bestFood nel programma

Il sesto compito di JavaScript era analizzare la dichiarazione della variabile bestFood della funzione.

Dopo l'analisi, JavaScript ha mantenuto automaticamente la variabile in una zona morta temporale, fino alla sua completa inizializzazione.

Pertanto, qualsiasi tentativo di accesso a bestFood prima della sua completa inizializzazione restituirebbe un ReferenceError.

7. Il computer ha analizzato l'istruzione console.log della funzione

console.log(bestFood);

Infine, il computer ha letto l'istruzione console.log, che indicava al sistema di stampare il contenuto di bestFood sulla console del browser.

Tuttavia, ricorda che il computer non ha ancora completamente inizializzato la variabile bestFood della funzione. In quanto tale, la variabile si trova attualmente in una zona morta temporale.

Pertanto, il tentativo del sistema di accedere alla variabile ha restituito un ReferenceError.

Nota: dopo aver restituito un  ReferenceError, il computer ha smesso di leggere il codice della funzione. Pertanto, JavaScript non ha inizializzato la variabile bestFood della funzione con "Riso saltato con verdure".

Ricapitolando

Vediamo la precedente analisi passo-passo del nostro programma in un unico pezzo:

let bestFood // 1. JavaScript ha analizzato la prima dichiarazione di bestFood

let myBestMeal // 2. il computer ha analizzato la dichiarazione della variabile myBestMeal

bestFood = "Pesce e patatine"; // 3. il computer ha inizializzato la variabile bestFood

myBestMeal = function () {
  console.log(bestFood);
  let bestFood = "Riso saltato con verdure";
}; // 4. JavaScript inizializza la variabile myBestMeal

myBestMeal(); // 5. il computer ha richiamato la funzione myBestMeal

let bestFood // 6. JavaScript ha analizzato la dichiarazione di bestFood della funzione

console.log(bestFood); // 7. il computer ha analizzato l'istruzione console.log della funzione

Uncaught ReferenceError // L'invocazione di bestFood ha restituito un errore

Puoi vedere che JavaScript ha elaborato le dichiarazioni nel programma prima dell'altro codice.

L'analisi delle dichiarazioni prima dell'altro codice in un programma è ciò che chiamiamo "sollevamento".

Panoramica

Questo articolo ha discusso del significato di zona morta temporale e sollevamento in JavaScript. Abbiamo anche usato degli esempi per illustrare come funzionano entrambi.

Grazie per aver letto!

Ed ecco un'utile risorsa per ReactJS:

Ho scritto un libro su React!

  • È adatto ai principianti ✔
  • Ha frammenti di codice in tempo reale ✔
  • Contiene progetti scalabili ✔
  • Ha molti esempi di facile comprensione ✔

Il libro React Explained Clearly è tutto ciò di cui hai bisogno per capire ReactJS.

Reagire spiegato chiaramente Prenota ora disponibile su Amazon