Język JavaScript do zarządzania zasięgiem zmiennych wykorzystuje funkcje. Zmienna zdefiniowana wewnątrz funkcji jest zmienną lokalną. Istnieje ona tylko wewnątrz funkcji.
Zmienna globalna natomiast jest zadeklarowana poza funkcją lub jest używana bez jakiejkolwiek deklaracji.
Środowisko JavaScript udostępnia obiekt globalny pod słowem kluczowym this ,pod warunkiem, że jest ono użyte poza funkcją lub bez żadnych deklaracji.
Każda zmienna globalna staje się właściwością obiektu globalnego.
W przeglądarkach istnieje właściwość “windows”, która zazwyczaj wskazuje na sam obiekt globalny.
Sprawdźmy to.
globalna = "jestem wszedzie";
console.log(globalna);
console.log(window.globalna);
console.log(window["globalna"]);
console.log(this.globalna);
Rzeczywiście to prawda
Gdzie jest problem
Zmienne globalne są problemem, ponieważ są one współdzielone przez cały kod strony www. Skoro istnieją w tym samym miejscu, to mogą nawzajem siebie zakłócać, jeśli zostały nieumyślnie zadeklarowane wiele razy, niekoniecznie przez tych samym programistów.
Sama witryna może także korzystać z wewnętrznych pluginów i skryptów reklamowych. Jeśli zewnętrzny skrypt zdefiniował zmienną globalną o nazwie “ad”, a później programista zdefiniuje jeszcze raz taką samą zmienną globalną, wtedy on zniweluje działanie zmiennej z zewnętrznego skryptu.
Nie chcemy szkodzić innym skryptom i musimy o to zadbać.
Warto też wspomnieć o tym, że globalne zmienne mają niską wydajność ponieważ żyją wewnątrz bogatej przestrzeni nazw. Globalne zmienne żyją razem z innymi domyślnie zdefiniowanymi zmiennymi JavaScript. Przeglądarka także musi poświęcić trochę czasu na odróżnianie zmiennych globalnych od właściwości obiektów w obecnym kontekście. Wiele obiektów w obecnym kontekście może być referowane za pomocą nazwanych zmiennych lub przez właściwość obiektów, takich jak alert().
Czasami zmienne globalne są równie szybkie jak zmienne lokalne, ale są to wyjątki.
Przypadkowe deklaracje zmiennych globalnych
Najprostszym sposobem na uniknięcie tworzenia zmiennych globalnych jest np. użycie słowa kluczowego var przed ich deklaracją.
Dwie cechy języka JavaScript ułatwiają nam przypadkowe utworzenie zmiennych globalnych.
- poprzez użycie zmiennych bez ich deklarowania
- poprzez dorozumienie zmiennych globalnych
Istnieje pewna różnica pomiędzy zmiennym globalnymi, a ich dorozumiewanymi odpowiednikami. Te drugie mogą być usunięte ponieważ w rzeczywistości są tylko właściwościami globalnego obiektu.
Dorozumienie zmiennych globalnych polega na tym, że dowolna zmienna, która nie została jawnie zadeklarowana staje się właściwością obiektu globalnego.
function calc(x, y){
sum = x + y;
return sum;
}
Zmienna “sum” jest zmienną globalną. Być może ktoś w przyszłości stworzy też taką zmienną globalną, nie mówiąc już o tym, że jej odczyt jest wolniejszy.
Aby ustrzec się przed takimi pułapkami deklarujemy zmienne przy pomocy słowa kluczowego “var”.
function calc(x, y){
var sum = x + y;
return sum;
}
Można także w inny sposób utworzyć zmienne globalne dorozumiane przez przypadek.
Oto łańcuch przypisań, jako części deklaracji przy użyciu “var”.
function whatever(){
var a = b = 0;
}
W powyższym fragmencie kodu zmienna “a” będzie zmienną lokalną, ale “b” stanie się zmienną globalną, czego nie oczekiwano.
Dlaczego tak się dzieje? Operacje wykonują się od prawej do lewej , czyli najpierw wykonuje się “b = 0” , a potem “var a = b”.
Aby zapobiec takiemu zachowaniu wystarczy zadeklarować wszystkie zmienne przy pomocy słowa kluczowego “var”.
function whatever() {
var a,b;
a = b = 0;
}
Kolejnym powodem do unikania zmiennych globalnych jest przenośność kodu pomiędzy środowiskami. Być może system ma już zarezerwowane właściwości globalne, a ty je nadpisujesz. Tworzy to też kolejny problem ponieważ nie masz nigdy 100% pewności, że twój kod zadziała wszędzie.
Przenoszenie deklaracji zmienna lokalna o tej samej nazwie co globalna
Ciekawostka. Co się stanie jeśli masz zmienną lokalną o tej samej nazwie, co zmienna globalna?
JavaScript oferuje stosowanie wielu poleceń “var” w dowolnym miejscu funkcji. Tajemnica jednak polega na tym, że wszystkie te deklaracje dają taki sam efekt, jakby były one wszystkie zadeklarowane na początku funkcji.
Działanie to naturalnie prowadzi do dziwnych błędów logicznych w zapisie programu, które dla człowieka nie mają sensu.
W języku JavaScript, jeśli zmienna znajduje się w tym samym zasięgu zmiennych, wtedy jest uważana za zadeklarowaną, nawet jeśli jest ona użyta przed deklaracją “var”.
>mygame = "Devil May Cry";
function func() {
alert(mygame);
var mygame = "X-COM";
alert(mygame);
}
func();
Najpierw wykona się alert wyświetlający wartość “undefined”. Jest to żywy dowód na to, że funkcja już na tym etapie zadeklarowała zmienną. Gdyby tak nie było wyświetliłaby się nam wartość zmiennej globalnej.
Po przypisaniu wartości wyświetla się nam znowu zmienna lokalna, tylko tym razem z przypisaną wartością.
Wzorzec pojedynczego var
Istnieje prosty wzorzec, który pomoże zapobiegać tworzeniu się zmiennych globalnych przez przypadek.
Nazywa się on wzorcem pojedynczego “var”. Ma następujące zalety:
- Zapewnia stałe miejsce wszystkich zmiennych lokalnych, wymaganych przez funkcje.
- Zapobiega problemowi, który został opisany powyżej. Wszystkie zmienne są deklarowane na początku.
- Zmniejsza ilość kodu
Jest on bardzo prosty:
function fafa() {
var a = 0,
b = 1,
tab = [1,2,3].
objectos = {}
}
fafa();