Zaskakujące, że zmienna globalna ma niezdefiniowaną wartość w JavaScript
Dzisiaj byłem całkowicie zaskoczony, gdy zobaczyłem, że zmienna globalna ma wartość undefined
w pewnym przypadku.
Przykład:
var value = 10;
function test() {
//A
console.log(value);
var value = 20;
//B
console.log(value);
}
test();
Daje wyjście jako
undefined
20
Tutaj, dlaczego silnik JavaScript traktuje wartość globalną jako undefined
. Wiem, że JavaScript jest językiem interpretowanym. Jak można rozpatrywać zmienne w funkcji?
Czy to pułapka z silnika JavaScript?
4 answers
Zjawisko to znane jest jako: JavaScript Variable Hoisting .
W żadnym momencie Nie uzyskujesz dostępu do zmiennej globalnej w swojej funkcji; uzyskujesz tylko dostęp do zmiennej lokalnej value
.
Twój kod jest odpowiednikiem:
var value = 10;
function test() {
var value;
console.log(value);
value = 20;
console.log(value);
}
test();
Nadal zaskoczony, że dostajesz undefined
?
Wyjaśnienie:
Jest to coś, na co prędzej czy później wpadnie każdy programista JavaScript. Mówiąc najprościej, niezależnie od zmiennych, które deklarujesz, są zawsze Podnoszone na szczyt twojego lokalnego zamknięcia. Tak więc, nawet jeśli zadeklarowałeś swoją zmienną po pierwszym wywołaniu console.log
, nadal jest ona traktowana tak, jakbyś zadeklarował ją wcześniej.
Jednak tylko część deklaracji jest podnoszona, z drugiej strony cesja nie jest.
Więc, kiedy po raz pierwszy wywołałeś console.log(value)
, odnosiłeś się do lokalnie zadeklarowanej zmiennej, która nie ma jeszcze nic przypisanego do niej; stąd undefined
.
Oto inny przykład :
var test = 'start';
function end() {
test = 'end';
var test = 'local';
}
end();
alert(test);
Jak myślisz, co to zaalarmuje? Nie, Nie czytaj dalej, myśl o tym. Jaka jest wartość test
?
Jeśli powiedziałeś coś innego niż start
, myliłeś się. Powyższy kod jest równoważny temu:
var test = 'start';
function end() {
var test;
test = 'end';
test = 'local';
}
end();
alert(test);
Aby zmienna globalna nigdy nie została naruszona.
Jak widzisz, bez względu na to, gdzie umieścisz swoją deklarację zmiennej, jest ona zawsze podniesiona na górze twojego lokalnego zamknięcia.
Side Uwaga:
Dotyczy to również funkcji.
Rozważmy 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 kawałek kodu działa dobrze:
test("Works!");
function test(text) { alert(text); }
Powodem tego, jak stwierdzono, jest to, że część przypisania jest , a nie podniesiona. Tak więc w pierwszym przykładzie, kiedy test("Won't work!")
został uruchomiony, test
zmienna została już zadeklarowana, ale nie ma jeszcze przypisanej funkcji.
W drugim przykładzie nie używamy przypisywania zmiennych. Zamiast tego używamy właściwej składni deklaracji funkcji, która sprawia, że funkcja jest całkowicie podniesiona.
Ben Cherry napisał doskonały artykuł na ten temat, odpowiednio zatytułowany JavaScript Scoping and Hoisting .
Przeczytaj. To da ci cały obraz w całości szczegóły.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-13 07:40:27
Byłem nieco rozczarowany, że problem tutaj został wyjaśniony, ale nikt nie zaproponował rozwiązania. Jeśli chcesz uzyskać dostęp do zmiennej globalnej w zakresie funkcji bez uprzedniego utworzenia niezdefiniowanego lokalnego var, odwołaj się do var jako window.varName
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-22 20:18:13
Zmienne w JavaScript zawsze mają zakres funkcji. Nawet jeśli zostały zdefiniowane w środku funkcji, są widoczne wcześniej. Podobne zjawiska można zaobserwować przy podnoszeniu funkcji.
To powiedziawszy, pierwsza console.log(value)
widzi zmienną value
(wewnętrzną, która zacienia zewnętrzną value
), ale nie została jeszcze zainicjowana. Można o tym myśleć tak, jakby wszystkie deklaracje zmiennych zostały pośrednio przeniesione na początek funkcji (, a nie w kodzie inner-most block), natomiast definicje są pozostawione w tym samym miejscu.
Zobacz też
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:47
Istnieje zmienna globalna value
, ale gdy kontrolka wchodzi w funkcję test
, deklarowana jest inna zmienna value
, która zacienia globalną. Ponieważ zmienne deklaracje (, ale nie przydziały) w JavaScript są podnoszone do góry zakresu, w którym są deklarowane:
//value == undefined (global)
var value = 10;
//value == 10 (global)
function test() {
//value == undefined (local)
var value = 20;
//value == 20 (local)
}
//value == 10 (global)
Zauważ, że to samo dotyczy deklaracji funkcji, co oznacza, że możesz wywołać funkcję, zanim pojawi się ona zdefiniowana w Twoim kodzie:
test(); //Call the function before it appears in the source
function test() {
//Do stuff
}
Warto również zauważyć, że gdy połącz te dwa wyrażenia w wyrażenie funkcji, zmienna będzie undefined
dopóki nie nastąpi przypisanie, więc nie możesz wywołać funkcji, dopóki tak się nie stanie:
var test = function() {
//Do stuff
};
test(); //Have to call the function after the assignment
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-31 19:47:05