@thefourtheye ha ragione dicendo che queste variabili non sono accessibili prima che vengano dichiarate. Tuttavia, è un po 'più complicato di così.
Le variabili dichiarate con let
o const
non vengono issate? Cosa sta succedendo davvero qui?
tutte le dichiarazioni (var
, let
, const
, function
, function*
, class
) sono "issato" in JavaScript. Ciò significa che se un nome è dichiarata in un ambito, in tale ambito l'identificatore farà sempre riferimento tale variabile:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
Questo è vero sia per funzioni e blocchi ambiti .
La differenza tra var
/function
/function*
dichiarazioni e let
/const
/class
DICHIARAZIONE zioni è il inizializzazione.
I primi sono inizializzati con undefined
o la funzione (generatore) destra quando l'associazione viene creata nella parte superiore dell'ambito. Le variabili dichiarate in modo lessicale rimangono tuttavia non inizializzate. Ciò significa che viene generata un'eccezione ReferenceError
quando si tenta di accedervi.Verrà inizializzato solo quando viene valutata l'istruzione let
/const
/class
, tutto prima (sopra) che è chiamato la zona zona morta.
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
Si noti che una dichiarazione let y;
inizializza la variabile con undefined
come let y = undefined;
avrebbe.
La zona morta temporale non è una posizione sintattica, ma piuttosto il tempo tra il (portata) creazione variabile e l'inizializzazione. Non è un errore fare riferimento alla variabile nel codice sopra la dichiarazione fintanto che quel codice non viene eseguito (es. Un corpo funzione o semplicemente codice morto), e genererà un'eccezione se si accede alla variabile prima dell'inizializzazione anche se l'accesso il codice è al di sotto della dichiarazione (ad es. in una dichiarazione di una funzione issata chiamata troppo presto).
C'è qualche differenza tra let
e const
in questa materia?
No, funzionano lo stesso per quanto riguarda il sollevamento. L'unica differenza tra loro è che un form const
deve essere e può essere assegnato solo nella parte inizializzatore della dichiarazione (const one = 1;
, entrambi const one;
e successive riassegnazioni come one = 2
non sono valide).
1: var
dichiarazioni stanno ancora lavorando solo a livello di funzione, ovviamente
@janaspage: Questo è quello che dice la risposta, vero? Btw, tutto tranne le dichiarazioni 'var' sono issate sullo scope block, non solo' let'. – Bergi
Ah, era implicito. Il sollevamento avviene sempre all'interno di un ambito e i blocchi sono l'ambito di tutto (tranne 'var'). – Bergi
Trovo che qualcosa come 'let foo =() => bar; let bar = 'bar'; foo(); 'illustra * tutte le dichiarazioni sono issate * l'effetto è ancora migliore, perché non è ovvio a causa della zona morta temporale. – estus