Postoji više načina da se definiše varijabla u JavaScriptu. Nešto stariji način je korištenjem ključne riječi var
. Međutim, ES6 standard JavaScripta je donio dvije nove ključne riječi za definisanje varijabli - let
i const
. U ovom tekstu ćete pročitati najosnovnije razlike između ova tri pristupa.
Kratka napomena: Tokom cijelog ovog teksta ću koristiti riječ varijabla, čak i u slučaju kada pričam o vrijednosti koja je ona definisana sa const
koja u suštini znači da je definisana vrijednost u suštini konstanta. Više o razlici između to dvoje u četvrtom poglavlju ovog teksta.
Šta će se sve moći pročitati u ovom tekstu?
- Razlika između var i let u opsegu
- Razlika između var i let u hoistingu
- Razlika u ponovnom deklarisanju
- Razlika između let i const
Razlika između var
i let
u opsegu (scope)
Šta je opseg?
Opseg je okruženje u kom je neka deklarisana vrijednost vidljiva. U JavaScriptu postoje tri opsega: globalni, funkcijski i blok.
Sve vrijednosti koje su deklarisane u globalnom opsegu su dostupne u cijelom programu. Bez obzira koja ključna riječ je korištena prilikom deklarisanja ta vrijednost će biti vidljiva u cijelom programu.
Dakle, bilo gdje u kodu imate pristup varijabli name
jer je ona ima globalni opseg. Funkcija logName
i console.log
imaju pristup varijabli name
.
Generalno govoreći treba izbjegavati deklarisanje globalnih varijabli, jer to otvara prostor za pojavljivanje različitih preklapanja i/ili poništavanja za drugim skriptama i bibliotekama.
U ovom kontekstu važno je naglasiti da će svaka varijabla koja je deklarisana bez ključne riječi automatski postati globalna varijabla.
Razlika između var i let dolazi u tome kada one nisu globalne varijable. Varijable deklarisane sa var
imaju opseg funkcije u kojoj su deklarisane.
Šta se dešava? Kada pozovete funkciju logName
ona vidi varijablu ime
jer opseg varijable ime
je ta funkcija. Međutim, kada pokušate da pristupite toj varijabli u console.log(ime)
tu ste već u globalnom opsegu i nemate pristup (ne vidite) varijabli ime
, te ćete zato dobiti grešku.
Za razliku od ovoga varijable deklarisane sa let
imaju opseg bloka koda. Blok koda u JavaScriptu je jednostavno rečeno sve što se nalazi unutar vitičastih zagrada {}
. To može biti if-else
izjava, switch
izjava, bilo koja petlja...
Šta se dešava? Imam if
izjavu (blok koda) unutar koje je deklarisanja varijabla ime
. Unutar istog tog bloka koda console.log(ime)
će viditi tu varijablu jer opseg te varijable je taj blok koda. Međutim, izvan ovog bloka ste u globalnom opsegu i nemate pristup varijabli ime
.
Varijabla deklarisana sa var
ovdje ne bi izbacila grešku.
Varijabla ime
bi u ovom slučaju imala globalni opseg i bila bi dostupna (vidljiva) drugoj console.log(ime)
izjavi.
Razlika između var
i let
u hoistingu
Još jedna od razlika između var
i let
ključne riječi je u ponašanju tokom takozvanog hoisting-a (podizanje). Ovo je mehanizam u kom su deklaracije funkcija i varijabli naizgled pomjerene na vrh (hoist) njihovog opsega. Upravo zbog ovog mehanizma možete imati pristup varijablama ili funkcijama prije njihovog deklarisanja.
Dakle, funkcija logName
ima pristup varijabli ime
zato što je varijabla ime
naizgled podignuta na vrh opsega (scope - global), ali treba obratiti pažnju na to da joj je vrijednost undefined
.
Upravo ovdje nastupa razlika između var
i let
. Ovaj princip hoisting-a će funkcionisati samo sa varijablama koje su deklarisane sa var
. Ukoliko bi pokušali iskoristiti let
za deklarisanje varijable dobićete grešku zato što varijable deklarisane sa let
neće biti podignute.
Riječ 'naizgled' je namjerno označena jer upravo tu dolazi objašnjenje. Ništa se ne podiže, prilikom egzekucije koda nijedna linija koda neće u stvari biti pomjerena. Podizanje je samo 'naizgled'.
Šta JavaScript engine radi kada čita kod?
Kada neki engine (komponenta koja je zadužena za izvršenje JavaScript koda) čita JavaScript kod on obavlja dva koraka: faza kreacije (creation phase) i faza izvršenja (execution phase).
U fazi kreiranja 'engine' deklariše svaku varijablu, dodijeli joj prostor u memoriji i početnu vrijednost
undefined
. Tada je varijabla deklarisana. Ovo je deklaracija varijable.U fazi izvršenja varijabla će dobiti vrijednost koja joj je dodijeljena u kodu. Npr. kada napišete
var ime = 'Slaven'
Ovo je inicijalizacija varijable.
Mehanizam podizanja će podići samo deklaraciju varijable, ali ne i inicijalizaciju. Upravo zbog ovoga varijable deklarisane sa var
imaju vrijednost undefined
kada pokušate da ih iskoristite prije inicijalizacije.
Međutim varijablama koje su deklarisane sa let
ne možete pristupiti prije inicijalizacije (drugi korak) i zato ćete dobiti grešku ReferenceError
ako pokušate da je iskoristite prije inicijalizacije. U suštini 'engine' vam govori: 'Vidim varijablu, deklarisana je, ali nije inicijalizovana i zato joj ne možete pristupiti'.
Napomena: Strogo govoreći varijable deklarisane sa let
i const
između ova dva koraka završavaju u nečemu što se zove 'temporal dead zone' (vremenska mrtva zona), objašnjenje toga bi zahtjevalo malo dublje obješanjenje faze kreacije i egzekucije (izvršenja), te sam smatrao da bi to trebalo biti tema za neki drugi tekst.
Razlika u ponovnom deklarisanju
Još jedna od razlika je u tome što varijable deklarisane sa var
mogu biti ponovo deklarisane sa istim imenom.
Ovo je validna JavaScript sintaksa ako se koristi var
. Druga deklaracija će poništiti prvu i zato će varijabla ime
nositi vrijednost 'John'.
Očigledno je koliko je ovo potencijalno problematično. Ne želite se naći u situaciji gdje nakon izvjesnog vremena pokušate ponovo deklarisati varijablu zato što ste možda zaboravili da već imate varijablu sa istim imenom.
Promjenu u ovom kontekstu došle su sa let
(kao i const
). Varijable deklarisane sa let
ne mogu biti ponovo deklarisane i dobićete grešku.
Ovo će izbaciti grešku SyntaxError
istog trenutka kada dođe do ponovo deklarisane varijable.
Razlika između let
i const
Varijable deklarisane sa let
i const
ponašaju identično u svim slučajevima o kojim sam govorio do sada (opseg, podizanje, ponovna deklaracija).
Razlika između ove dvije ključne riječi je u tome što varijablama koje su deklarisane sa let
mogu dodijeliti novu vrijednost negdje drugo dok varijable koje su deklarisane sa const
to ne dozvoljavaju i to je svrha njihovog uvođenja.
Ovo ne treba pomiješati sa onim što sam govorio u prethodnom poglavlju da let
varijable ne mogu biti ponovo deklarisane. Ovdje varijabla ime
nije ponovo deklarisana nego joj je samo dodijeljena druga vrijednost.
Međutim, ključna riječ const
ovo ne dozvoljava.
Ovo nije dozvoljeno i dobićete grešku istog trenutka kada dođe do ponovnog dodjeljivanja vrijednosti. Kao što navedena greška kaže, nije dozvoljeno dodjeljivati vrijednost konstantama.
Jedna stvar na koju treba obratiti pažnju kod const
varijabli je to kako se one ponašaju kada nose vrijednost referentnih tipova podataka, kao što su objekti ili nizovi. Iako ni ovdje nije dozvoljeno ponovo dodjeljivati vrijednost, dozvoljeno je mijenjati same elemente unutar te vrijednosti.
Ovdje imamo objekat korisnik
koji ima dva svojstva. Nakon toga je promijenjeno svojstvo godine
u tom objektu.
Ovo je dozvoljeno u JavaScriptu čak i sa const
varijablama. Ovo se naziva mutacija varijabli. Dakle, dozvoljeno je mijenjati pojedinačna svojstva unutar objekta, ali nije dozvoljeno ponovo dodijeliti vrijednost cijeloj varijabli.
Postoje načini da se zamrznu neka svojstva u objektima, ali to je tema koju vrijedi ispitadi u zasebnom tekstu.
Zaključak
Izbjegavajte korištenje globalnih varijabli. Ovo otvara previše prostora za preklapanje naziva varijabli iz različitih skripti ili biblioteka.
Uglavnom bi trebalo izbjeći korištenje
var
ključne riječi za deklarisanje varijabli sada kada imamo na raspolaganjulet
iconst
. Varijable savar
prljaju globalni (window) objekat, a to je poželjno izbjeći.Koristite
const
za deklarisanje varijabli ako možete predviditi da ta varijabla neće dobijati drugu vrijednost. Ako imate razloga da mislite da će nekad tokom njenog korištenja ta varijabla dobiti drugu vrijednost slobodno možete koristitilet
ključnu riječ.
Top comments (0)