Czytam sobie ostatnio do poduszki obiektowy JS, tak w ramach powtorzenia. Poniewaz dziergam w tym jezyku kilka lat juz coraz mniej mnie dziwi. Aczkolwiek kwestia, z ktora sobie dosc dlugo nie moglam poradzic byl zasieg zmiennych.
Zalozmy ze mamy kod:
var a = 1;
function f() {
console.log('1. ' + a);
var a = 2;
console.log('2. ' + a);
}
f();
Zasieg zmiennych w JS jest ograniczony nie do nawiasow klamrowych, a do funkcji (od ES6 tylko dla słowa kluczowego
var). Jesli zmienna jest w globalnej przestrzeni nazw (bez slowka
var) to jest osiagalna praktycznie z dowolnego miejsca. Slowko
var ogranicza zasieg, np do danego pliku czy funkcji.
Co bedzie wynikiem dzialania takiego kodu? Otoz zmienne sa widoczne w srodowiskach zawartych, ale nie na zewnatrz. Wiec jesli na zewnatrz funkcji mamy zdefiniowana zmienna a, a wewnatrz funkcji tworzymy ja jeszcze raz (slowko
var), to JavaScript bedzie widzialo ta zmienna wewnatrz funkcji, jako zmienna o zasiegu tylko na te funkcje. Zaskutkuje to tym, ze pierwszy
console.log wypisze nam
undefined. Dlaczego? Bo wewnatrz funkcji ta zmienna JESZCZE nie ma wartości (interpreter już wie, że będzie stworzona, ale jeszce w tej linii kodu nie ma wartości; stąd dobra praktyka tworzyć WSZYSTKIE zmienne na początku funkcji/bloku kodu, żeby uniknąć takich sytuacji), wiec by default ma przypisana wartosc
undefined. Drugi
console.log wypisze juz, zgodnie z oczekiwaniami wartosc 2.
Zmodyfikujmy troche nasz kod:
var a = 1;
function f() {
console.log('1. ' + a);
a = 2;
console.log('2. ' + a);
}
f();
Mala roznica. Wenatrz funkcji usunelam slowo
var przed definicja zmiennej lokalnej a. Co to zmienia z punktu widzenia naszego programu? Wszystko. Przede wszytkim JavaScript sprawdzi, czy w zasiegu dostepnym z wnetrza funkcji nie ma juz zmiennej a. Jesli jest (jak w naszym przypadku) to zmieni jej wartosc.
Nasz program wypisze dwa razy wartosc zmiennej a widoczna wewnatrz funkcji. Za pierwszym razem bedzie to 1, a za drugim 2 (wartosc zmieniona juz wewnatrz funkcji)
To teraz tylko sprawdzenie, jak to wyglada na zewnatrz funkcji:
var a = 1;
function f() {
console.log('1. ' + a);
a = 2;
console.log('2. ' + a);
}
console.log('3. ' + a);
f();
console.log('4. ' + a);
Zgodnie z oczekiwaniami zmienna istnieje w kazdym przypadku i zmiana jej wartosci wewnatrz funkcji skutkuje zmiana rowniez poza funkcja, bo operujemy na zmiennej o zakresie szerszym niz zakres tej funkcji.