Zmienne i stałe

Zmienne to coś w rodzaju "pudełek", w których pod nazwami możemy przechowywać różne rzeczy takie jak liczby, teksty, obiekty itp.

Deklarowanie zmiennych

Aby zadeklarować zmienną, powinniśmy posłużyć się jednym ze słów kluczowych. Do stworzenia zmiennej w JavaScript przez lata używało się słowa kluczowego var:

var txt = "Ala ma kota";
var nr = 20;
var url = "kontakt.html";

console.log(txt);
console.log(nr);
console.log(url);

JavaScript ewoluuje. W 2015 roku pojawiła się ECMAScript 2015 wprowadzając sposoby deklaracji zmiennych za pomocą słów let i const. Słowo let oznacza zmienną, natomiast const stałą:

let txt = "Przykładowy tekst"; //zmienna
txt = "Inny tekst"; //zmieniamy wartość

const nr = 102; //stała
nr = 103; //błąd - nie można przypisać nowej wartości

W dzisiejszych czasach mimo tego, że w internecie spotkamy miliony skryptów wykorzystujących var, zaleca się stosować const i let. Dzięki nim nasze skrypty nie tylko działają lepiej pod względem zarządzania pamięcią, ale i potencjalnie unikamy niektórych problematycznych sytuacji, które występowały przy var (a o których dowiesz się w dalszej części kursu).

Przeglądając Internet zapewne natrafisz na wiele przykładów skryptów, gdzie autorzy tworzą zmienne z pominięciem słów kluczowych var/let/const np:

Nie rób tak. Tworząc zmienne nie pomijaj słów let/const/var. W kolejnych rozdziałach dowiesz się czemu.

Po co stosować zmienne?

Po co w ogóle stosować zmienne? Rozpatrzmy prosty przykład dodawania liczb:

Przypuśćmy, że teraz chcielibyśmy zmienić cyfrę 5 w każdym równaniu.

Dla tak małego skryptu zmiana tej cyfry nie jest wielkim problemem. Co by się jednak stało gdybyśmy takich równań w naszym przykładzie mieli na przykład tysiąc lub nawet sto tysięcy? I tu właśnie przychodzą nam z pomocą zmienne:

Pod zmienne możemy podstawiać nie tylko liczby, ale teksty, funkcje, obiekty, tablice - czyli dowolne rzeczy, na których będziemy pracować w naszych kodach:

Nazewnictwo zmiennych

Nazwy zmiennych i stałych które deklarujemy nie mogą być byle jakie. Istnieją pewne zasady których musimy się trzymać. I tak:

  • wielkość liter ma znaczenie. Zmienna myTXT to nie to samo co mytxt

  • nazwa zmiennej nie może zaczynać się od cyfry,

  • nazwa zmiennej nie może zawierać spacji, kropki, przecinka ani myślnika (można natomiast używać podkreślenia),

  • nazwą zmiennej nie może być słowo kluczowe zarezerwowane przez JavaScript

Po prostu nie zaczynaj nazw od cyfr i pisz nazwy zmiennych po angielsku. Bardzo częstą praktyką jest stosowanie zapisu camelCase, czyli np. veryImportantThing, ale wiele osób stosuje też zapis z podłogą czyli very_important_thing.

Jest jednak ważniejsza sprawa, którą zapamiętaj. Nazywaj swoje zmienne tak, by dało się zrozumieć do czego się odnoszą. Zmienna o nazwie elementsCount jest bardziej czytelna, niż xxx. W tym kursie czasami będę korzystał z mało czytelnych zmiennych (np. a), ale wynika to tylko z tego, że kod często jest bardzo, bardzo krótki, a i jestem leniem.

Dla ciekawskich - nazwy zmiennych mogą być bardzo różne. Nie jest to oczywiście zalecane i trzeba to traktować jako ciekawostkę.

const

Jedną z głównych bolączek var od zawsze było to, że za pomocą tego słowa można tworzyć tylko zmienne. Oznacza to, że w każdym momencie mogę później taką zmienną zmienić:

W celu uniknięcia błędów część programistów nazywało stałe dużymi literami. Dzięki temu osoba pisząca kod wiedziała czy powinna czy nie powinna zmieniać danej zmiennej.

...konwencja ta jest nadal przez wielu stosowana - co jest akurat bardzo spoko, ponieważ po samej nazwie zmiennej nie sposób wykryć czy można zmienić jej wartość.

Wraz z wprowadzeniem nowych słów let/const dostaliśmy rozróżnienie na zmienne i stałe. Zmienne deklarowane za pomocą let/var można w przyszłości zmienić - czyli podstawić im nową wartość. Zmiennym stworzonym za pomocą const nie jesteśmy w stanie podstawić nowej wartości.

Jeżeli jednak pod daną stałą const podstawimy jakiś obiekt, bez problemu będziemy mogli zmieniać jego właściwości:

Różnice między var a let/const

Deklaracje let/const nie tylko wprowadziły stałe, ale także kilka różnic w stosunku do var.

Pierwsza i najważniejsza różnica między let/const a var to zasięg zmiennych.

W przypadku let/const zmienne mają zasięg blokowy, co w skrócie oznacza "od klamry do klamry":

Zmienne deklarowane za pomocą var mają natomiast zasięg funkcyjny, czyli ich zasięg określa ciało funkcji.

W nielicznych sytuacjach może to powodować niezamierzone działanie kodu.

W kolejnych rozdziałach natrafisz na przykłady bardziej praktyczne...

Kolejna cecha rozróżniająca var od let/const jest taka, że zmienne var możemy ponownie deklarować, co jest niemożliwe w przypadku let i const:

W przypadku const/let musimy stosować inne bloki:

Kolejna różnica między starszą deklaracją var a jej młodszymi braćmi to tak zwany hoisting (windowanie). JavaScript lubi pomagać programiście. Jednym z takich przypadków pomocy jest niewidoczne dla programisty wynoszenie deklaracji "na początek kodu" (w pierwszym momencie twój kod czytany jest przez silnik Javascript (jest parsowany), a następnie tworzony jest specjalny "kontekst wykonawczy", czyli miejsce w pamięci, gdzie zawarte są wszystkie zmienne i funkcje używane przez ciebie - bardzo dobrze opisuje to film https://www.youtube.com/watch?v=Fd9VaW0M7K4).

W przypadku var odwołanie się do zmiennej przed jej stworzeniem nie rzuci nam błędem, natomiast pokaże undefined:

Deklaracja zmiennej bez wartości wynoszona jest automatycznie na początek danego kodu (a w zasadzie na początek danego zakresu - np. na początek danej funkcji), w wyniku czego nasz powyższy skrypt w momencie wykonywania ma postać:

Niektórzy programiści - szczególnie ci, którzy na co dzień używali innych języków, w których takie zjawisko nie występuje - dla uniknięcia takich niejawnych (a i niewidocznych dla nas) zachowań - stosowali konwencję deklaracji każdej zmiennej na początku kontekstu:

W przypadku let/const (ale też class) hoisting także istnieje, ale nie jesteśmy w stanie używać zmiennych przed ich zadeklarowaniem:

To samo będzie się tyczyło wyrażeń funkcyjnych, czyli sytuacji, gdzie funkcję podstawiamy pod zmienną. Znowu - nie możemy użyć zmiennej przed jej stworzeniem:

Ale o tym porozmawiamy sobie w rozdziale o funkcjach.

Miejsce przed deklaracją zmiennej let/const zwie się temporal dead zone, bo nie możemy odwoływać się do zmiennej, której jeszcze nie zadeklarowaliśmy. Dzięki takiemu zabiegowi nasz kod staje się bardziej logiczny - najpierw tworzymy wszystkie klocki (zmienne, funkcje), a dopiero potem ich używamy.

Ostatnią różnicą - dość mało znaną - jest to, że deklarując zmienną globalną var (poza ciałem funkcji), dodawana jest ona jako właściwość obiektu window. W przypadku let nic takiego się nie dzieje:

Gdy wypiszemy sobie w konsoli obiekt window, pokaże nam się masa różnych rzeczy, które możemy (i zapewne będziemy) używać:

Tworząc w powyższy sposób globalne zmienne var, moglibyśmy przez przypadek nadpisać niektóre funkcjonalności, które w przyszłości chcielibyśmy użyć:

Przy czym nie powinienem tutaj demonizować. Jeżeli piszesz swoje skrypty cokolwiek ponad 0 poziom wtajemniczenia, to raczej nie powinieneś nigdy natrafić na takie błędy. Ale któż wie...

To jak jesteśmy przy głupotach JS (o czym można by niezły art napisać), to jedną z kolejnych rzeczy jest fakt, że dla każdego elementu z ID tworzona jest zmienna o takiej samej nazwie, która wskazuje na dany element:

W odczuciu autora tego kursu jest to złe, ponieważ dostajemy zmienne, które powstają z nieba. Jeżeli będziemy pracować na elementach z ID, mimo że JavaScript stworzył dla nich zmienne, mimo wszystko lepszym wydaje się je jawnie pobrać za pomocą odpowiednich funkcji. Ale to już w rozdziale o DOM

Podsumowanie

Ok podsumujmy powyższe rozważania.

  • Zmienne to rodzaje pudełek, w których możemy trzymać różne rzeczy.

  • Zmienne możemy tworzyć za pomocą słów kluczowych var/let/const, przy czym zalecane są te dwa ostatnie

  • Let/const różnią się od varów głównie zasięgiem oraz tym, że w jednym zasięgu (bloku) nie możemy ponownie tworzyć zmiennych o tej samej nazwie.

  • Hoisting to zjawisko wynoszenia na początek skryptu zmiennych i deklaracji funkcji

  • W naszych skryptach starajmy się używać jak najwięcej const - dzięki temu będziesz wyglądał jak pro. Jedynym wyjątkiem są liczniki oraz zmienne które wiemy, że zaraz zmienimy (np. toggleCatNightPartyMode)

I w zasadzie tyle. Cała reszta przyjdzie z praktyką. Nawet jeżeli na chwilę obecną powyższe rozważania wydają się dla ciebie dziwne, nie przejmuj się. Po 2-3 skryptach całość stanie się odruchem.

Last updated