Zakres blokowy #26
Zakres blokowy
Kolejnym zakresem, który sobie omówimy, jest zakres blokowy. Przed wersją ES6
zakres blokowy praktycznie nie istniał, zobaczmy najprostszy przypadek kodu:
{
var x = '1';
const y = '2';
let z = '3';
}
Stworzyłem blok za pomocą dwóch nawiasów klamrowych. Tworzenie takich bloków kodu jest możliwe, ale raczej na co dzień nie spotkacie się z takimi blokami kodu w aplikacjach JavaScript.
Gdy wypiszemy te zmienne do konsoli:
console.log(x); // 1
// console.log(y); // error
// console.log(z); // error
Widzimy, że mamy dostęp tylko do zmiennej x
natomiast pozostałe zmienne, które zadeklarowane są za pomocą const
i let
nie są dostępne. Oznacza to, że zmienne zadeklarowane za pomocą var
nie respektują zakresu blokowego. Zmienna var
w tym przypadku jest zadeklarowana globalnie w obiekcie window
. Zakres bloku nie ma dla niej znaczenia.
Naprawiono to dopiero w ESCMAScript 6 wprowadzając deklaracje const
i let
.
Oczywiście takiego kodu blokowego raczej nie piszemy, a jak już używamy let
i const
. Jednak warto zwrócić uwagę, że z var
są także problemy w innych blokach kodu:
for (var i = 0; i < 5; i++) {
console.log(i) // 1, 2, 3, 4
}
console.log(i) // 5
Jest to jeden z najbardziej znanych przykładów braku zakresu bloku dla zmiennych var
. Zadeklarowana zmienna var
na potrzeby funkcji nadal była dostępna spoza tego bloku. Programista przez nieuwagę w dalszej części mógł jeszcze raz użyć zmiennej i
. Rozwiązaniem jest tutaj użycie
deklaracji let
.
Problemy te dotyczą oczywiście innych instrukcji blokowych jak if
, while
:
if (true) {
var a = 'bar';
const b = 'foo';
}
console.log(a)
// console.log(b) // error
Tutaj nadal mamy dostęp do zmiennej a
zadeklarowanej w bloku if
. Dlatego najlepszą opcją jest nieużywanie zmiennych deklarowanych za pomocą var
. Dla tych zmiennych zakres blokowy nie istnieje i wpadają one zawsze do obiektu globalnego i są dostępne globalnie.
Co warto zapamiętać
-
zmienna
var
nie przestrzega zakresu blokowego, używanievar
w blokach jest jednoznaczne z tworzeniem zmiennych globalnych -
dopiero
let
iconst
wprowadzone w ECMAScript 6 przestrzegają zakresu blokowego, między innymi takich jakif
orazfor
-
dobra rada nie używamy
var