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
}
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
}
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
}
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
}
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"
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.