Questo fenomeno è noto come: JavaScript Variable Hoisting .
In nessun momento stai accedendo alla variabile globale nella tua funzione; stai accedendo solo alla value
variabile locale .
Il tuo codice è equivalente al seguente:
var value = 10;
function test() {
var value;
console.log(value);
value = 20;
console.log(value);
}
test();
Sei ancora sorpreso undefined
?
Spiegazione:
Questo è qualcosa in cui ogni programmatore JavaScript prima o poi si imbatte. In poche parole, qualunque variabile dichiari viene sempre sollevata in cima alla tua chiusura locale. Quindi, anche se hai dichiarato la tua variabile dopo la prima console.log
chiamata, è ancora considerata come se l'avessi dichiarata prima.
Tuttavia, viene sollevata solo la parte della dichiarazione; il compito, invece, non lo è.
Quindi, quando hai chiamato per la prima volta console.log(value)
, stavi facendo riferimento alla tua variabile dichiarata localmente, a cui non è stato ancora assegnato nulla; quindi undefined
.
Ecco un altro esempio :
var test = 'start';
function end() {
test = 'end';
var test = 'local';
}
end();
alert(test);
Cosa pensi che questo avvertirà? No, non limitarti a leggere, pensaci. Qual è il valore di test
?
Se hai detto qualcosa di diverso da start
, ti sei sbagliato. Il codice sopra è equivalente a questo:
var test = 'start';
function end() {
var test;
test = 'end';
test = 'local';
}
end();
alert(test);
in modo che la variabile globale non sia mai influenzata.
Come puoi vedere, indipendentemente da dove metti la tua dichiarazione di variabile, viene sempre issata in cima alla chiusura locale.
Nota a margine:
Questo vale anche per le funzioni.
Considera questo pezzo di codice :
test("Won't work!");
test = function(text) { alert(text); }
che ti darà un errore di riferimento:
Errore di riferimento non rilevato: il test non è definito
Questo allontana molti sviluppatori, poiché questo pezzo di codice funziona bene:
test("Works!");
function test(text) { alert(text); }
Il motivo, come affermato, è perché la parte di assegnazione non viene sollevata. Quindi nel primo esempio, quando è test("Won't work!")
stata eseguita, la test
variabile è già stata dichiarata, ma non le è stata ancora assegnata la funzione.
Nel secondo esempio, non stiamo usando l'assegnazione di variabili. Piuttosto, stiamo usando sintassi corretta dichiarazione di funzione, che fa ottenere la funzione completamente issato.
Ben Cherry ha scritto un eccellente articolo su questo argomento , appropriatamente intitolato JavaScript Scoping and Hoisting .
Leggilo. Ti darà l'intera immagine in dettaglio.