English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Ambito (Scoping)
Per i principianti di JavaScript, un punto più confuso è l'ambito; in realtà, non solo i principianti. Ho incontrato alcuni programmatori JavaScript esperti, ma la loro comprensione dell'ambito non è profonda. L'ambito di JavaScript è confuso perché il suo linguaggio di programmazione è lungo come i linguaggi della famiglia C. La mia comprensione dell'ambito è che ha un'azione solo su un certo ambito e non ha un impatto esterno. In tali spazi, l'esterno non può accedere alle variabili interne, ma l'interno può accedere alle variabili esterne.
Le variabili del linguaggio C sono divise in variabili globali e variabili locali, l'ambito di azione delle variabili globali è qualsiasi file e funzione di accesso (naturalmente, per altri file C che non definiscono variabili, è necessario utilizzare la parola chiave extern per dichiararle, è possibile anche utilizzare la parola chiave static per limitare l'ambito di azione al file corrente), l'ambito di azione delle variabili locali è solo dalla dichiarazione al blocco di livello superiore coperto dal parentesi graffati. Java non ha variabili globali, ha variabili di classe, variabili di membro e variabili locali, l'ambito di azione varia a seconda dei permessi di accesso come public, protected, private, ecc., non sarà spiegato in dettaglio qui.
Quali sono i domini di scopo di JavaScript?
In ES5, JavaScript ha solo due tipi di domini di scopo: dominio di scopo globale e dominio di scopo della funzione.
Il dominio di scopo globale è il dominio di scopo dell'oggetto globale, può essere acceduto ovunque (se non coperto dal dominio di scopo della funzione).
Il dominio di scopo dell'oggetto funzione è diverso dal dominio di scopo delle variabili locali in C, il suo dominio di scopo è l'intera portata della funzione, indipendentemente dal punto in cui è stata dichiarata! Questo è ciò che si chiama hoisting, o promozione delle variabili. Tuttavia, non preoccuparti, in seguito esploreremo in dettaglio il concetto di hoisting.
Tuttavia, in ES6, è stata introdotta una scopa di blocco (il raggio coperto dal cerchio più recente), ma è limitata alle variabili dichiarate con let.
Dimostrazione di dominio di scopo:
Quando si definisce una variabile senza scrivere var, ad esempio i=0, viene definita come variabile globale, con dominio di scopo globale, altrimenti viene definita come variabile locale, con dominio di scopo della funzione. La prima riga var i=0 viene definita come variabile globale perché è stata dichiarata nell'area globale, non all'interno della funzione, quindi è uguale a i=0.
Riguardo al motivo per cui il risultato è così, continua a leggere per scoprirlo.
Forma di dichiarazione
Dichiarazione delle variabili
Dichiarazione di funzione:
Promozione delle variabili (Hoisting)
Introduco un problema
Qual è il contenuto che questo pezzo di codice stamperebbe?
Ho intervistato molte persone per questo problema, la maggior parte delle quali ha detto che il risultato è la data. Ma il risultato reale è undefined. Perché? Questo ci porta a introdurre un concetto: hoisting, che significa "promozione delle variabili" in cinese. Ecco come MDN spiega il concetto di hoisting delle variabili:
hoisting di var
Poiché le dichiarazioni di variabile (e in generale le dichiarazioni) vengono elaborate prima di eseguire qualsiasi codice, dichiarare una variabile in qualsiasi punto del codice è equivalente a dichiararla in alto. Questo significa anche che una variabile può sembrare essere utilizzata prima della sua dichiarazione. Questo comportamento è chiamato "hoisting", poiché sembra che la dichiarazione della variabile venga spostata in alto nel codice globale o nella funzione.
Questa frase tradotta è: }}
Poiché la dichiarazione delle variabili viene trattata prima dell'esecuzione di qualsiasi altro codice, dichiarare una variabile in qualsiasi parte del codice è uguale a dichiararla all'inizio (all'inizio). Questo significa che sembra che una variabile possa essere utilizzata prima della sua dichiarazione! Questo comportamento è chiamato 'hoisting', ovvero promozione delle variabili, sembra che la dichiarazione della variabile venga automaticamente spostata alla parte superiore del codice della funzione o del codice globale.
Attenzione:La promozione riguarda solo la dichiarazione, non la definizione.
Quindi, questo pezzo di codice è in realtà della forma seguente:
Quindi, è chiaro che quando console restituisce, la variabile tmp è stata solo dichiarata ma non definita, quindi il risultato dovrebbe essere undefined.
Occorre chiarire che tutte le dichiarazioni (inclusi var, function di ES5 e function *, let, const, class di ES6) vengono promosse, ma la promozione di var, function, function * e let, const, class non è la stessa! La ragione specifica può essere vista inQuesta spiegazione(Il senso generale è che anche let, const, class vengono promossi, ma non vengono inizializzati, quindi l'accesso a loro genera un'eccezione ReferenceError. Devono essere inizializzati solo quando vengono eseguiti i comandi, e lo stato prima dell'inizializzazione si chiama temporal dead zone). Vediamo un pezzo di codice per capire:
Qui a è stato promosso, ma poiché è stato definito dopo, viene restituito undefined
Qui a, anche se è stato promosso, ha riportato un errore di riferimento!
Per questo motivo o così
Per questo motivo, si consiglia di scrivere tutte le variabili utilizzate nella parte superiore dello scope (scope globale o di funzione), in modo che il codice sia più chiaro e più facile da capire quale variabile proviene dallo scope di funzione e quale dall'chain di scope (non entrerò nei dettagli di questo argomento, il lettore può cercare su Baidu, e sarà spiegato in modo più dettagliato in un'altra occasione).
Dichiarazione duplicata
L'output sopra è in realtà: 1 2 2. Anche se sembra che x sia stato dichiarato due volte, come è stato detto, i variabili var di js hanno solo due scope: globale e di funzione, e la dichiarazione viene promossa, quindi effettivamente x viene dichiarato una sola volta all'inizio, la dichiarazione var x=2 viene ignorata e viene utilizzata solo per l'assegnazione. Questo significa che il codice sopra è effettivamente uguale al seguente.
Il problema della promozione contemporanea di funzione e variabile
Se si definiscono contemporaneamente una funzione e un tipo di variabile, cosa accade? Guarda il codice seguente
A
Il risultato di output sopra è in realtà: function foo(){} , che è il corpo della funzione.
E se è così
B
Ma l'output diventa: undefined
Perché è così?
Originariamente, l'elevazione delle funzioni si suddivide in due casi:
Un altro: dichiarazione di funzione. È il seguente A, function foo(){}.
Un altro: espressione di funzione. È il seguente B, var foo=function(){}.
La seconda forma è in realtà la dichiarazione e la definizione della variabile var, quindi il risultato di output di B dovrebbe essere chiaro: undefined.
Mentre la prima forma di dichiarazione della funzione, durante l'elevazione, viene elevata interamente, inclusa la parte della definizione della funzione! Pertanto, A e il seguente metodo sono equivalenti!
Il motivo è che: 1. La dichiarazione della funzione viene elevata al livello più alto; 2. La dichiarazione viene eseguita una volta sola, quindi la dichiarazione var foo='i am text' viene ignorata.
E poiché la priorità della dichiarazione della funzione è superiore a quella della dichiarazione delle variabili, quindi anche le seguenti espressioni sono contenute nel corpo della funzione:
Conclusione
Per comprendere completamente il concetto di scope e Hoisting in JS, è sufficiente ricordare i seguenti tre punti:
1. Tutte le dichiarazioni vengono elevate al livello più alto dell'ambito.
2. La dichiarazione della stessa variabile viene eseguita una volta sola, e quindi altre dichiarazioni vengono ignorate.
3. La priorità della dichiarazione della funzione è superiore a quella della dichiarazione delle variabili, e la dichiarazione della funzione viene elevata insieme alla definizione.
Attenzione:
Con la frase with, è possibile modificare temporaneamente l'ambito di esecuzione della catena di scope, in questo caso l'accesso ai variabili non definite con var, verrà effettuato prima sugli attributi dell'oggetto con with e poi lungo la catena di scope verso l'alto per verificare l'attributo.
Questo è tutto il contenuto dell'articolo, spero che il contenuto di questo articolo possa aiutare la tua apprendimento o lavoro, se hai domande puoi lasciare un messaggio per discuterli.