Zjawisko to jest znane jako: JavaScript Variable Hoisting .
W żadnym momencie nie uzyskujesz dostępu do zmiennej globalnej w swojej funkcji; zawsze uzyskujesz dostęp tylko do value
zmiennej lokalnej .
Twój kod jest równoważny z następującym:
var value = 10;
function test() {
var value;
console.log(value);
value = 20;
console.log(value);
}
test();
Wciąż jesteś zaskoczony undefined
?
Wyjaśnienie:
Jest to coś, na co prędzej czy później wpada każdy programista JavaScript. Mówiąc najprościej, wszelkie zadeklarowane zmienne są zawsze przenoszone na szczyt lokalnego zamknięcia. Tak więc, nawet jeśli zadeklarowałeś swoją zmienną po pierwszym console.log
wywołaniu, nadal uważa się, że zadeklarowałeś ją wcześniej.
Jednak podnoszona jest tylko część deklaracji; z drugiej strony zadanie to nie jest.
Tak więc, kiedy pierwszy raz dzwoniłeś console.log(value)
, odnosiłeś się do swojej lokalnie zadeklarowanej zmiennej, która nie ma jeszcze nic przypisanego; stąd undefined
.
Oto kolejny przykład :
var test = 'start';
function end() {
test = 'end';
var test = 'local';
}
end();
alert(test);
Jak myślisz, co to ostrzeże? Nie, nie tylko czytaj dalej, pomyśl o tym. Jaka jest wartość test
?
Jeśli powiedziałeś coś innego niż start
, byłeś w błędzie. Powyższy kod jest równoważny z tym:
var test = 'start';
function end() {
var test;
test = 'end';
test = 'local';
}
end();
alert(test);
tak, aby nigdy nie wpływać na zmienną globalną.
Jak widać, bez względu na to, gdzie umieścisz swoją deklarację zmiennej, zawsze jest ona podnoszona na szczyt lokalnego zamknięcia.
Dygresja:
Dotyczy to również funkcji.
Rozważ ten fragment kodu :
test("Won't work!");
test = function(text) { alert(text); }
co da ci błąd odniesienia:
Uncaught ReferenceError: test nie jest zdefiniowany
To wyrzuca wielu programistów, ponieważ ten fragment kodu działa dobrze:
test("Works!");
function test(text) { alert(text); }
Jak już wspomniano, powodem tego jest to, że część przypisania nie jest podnoszona. Tak więc w pierwszym przykładzie, kiedy test("Won't work!")
została uruchomiona, test
zmienna została już zadeklarowana, ale nie ma jeszcze przypisanej do niej funkcji.
W drugim przykładzie nie używamy przypisywania zmiennych. Zamiast tego używamy prawidłowej składni deklaracji funkcji, która całkowicie podnosi funkcję.
Ben Cherry napisał doskonały artykuł na ten temat, odpowiednio zatytułowany JavaScript Scoping and Hoisting .
Przeczytaj to. Daje ci to pełny obraz ze szczegółami.