DEV Community

Slaven Bunijevac
Slaven Bunijevac

Posted on

Definisanje varijabli u JavaScriptu - var, let ili const

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.

example code of JavaScript global scope

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.

automatic global variable js example

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.

JavaScript function scope example code

Š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...

JavaScript block scope example

Š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.

JavaScript example block scope code with var

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.

example code for JavaScript var hoisging

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.

example JavaScript code hoisting with let variable

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).

  1. 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.

  2. 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.

example code of JavaScript redeclaration with var

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.

example JavaScript code for redeclaration with let

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.

example JavaScript code for value change with let

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.

example JavaScript code for redeclaration with const

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.

example of JavaScript code for const object property change

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 raspolaganju let i const. Varijable sa var 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 koristiti let ključnu riječ.

Top comments (0)