Šta tačno predstavlja ključna reč this
u JavaScript-u? Kako se ona može efikasno primeniti u vašem JavaScript kodu? Ovo su česta pitanja koja postavljaju kako početnici, tako i iskusniji JavaScript programeri kada je u pitanju razumevanje ključne reči this
.
Ako ste i vi među programerima koji se pitaju o značenju ove ključne reči, ovaj tekst je za vas. Detaljno ćemo istražiti na šta se this
odnosi u različitim situacijama, upoznaćemo se sa potencijalnim problemima kako bismo izbegli konfuziju i naravno, greške u vašem kodu.
this
u globalnom kontekstu
U globalnom kontekstu, this
referencira objekat window
sve dok se ne nalazi unutar funkcije. Globalni kontekst znači da se this
ne koristi unutar definicije neke funkcije.
if(true) { console.log(this) } let i = 2 while(i < 10) { console.log(this) i++ }
Ukoliko pokrenete gornji kod, kao rezultat ćete dobiti window
objekat.
this
unutar funkcija (metoda)
Kada se koristi unutar funkcije, this
se odnosi na objekat na koji je funkcija vezana. Izuzetak je kada se this
koristi u samostalnoj funkciji, u kom slučaju vraća window
objekat. Pogledajmo neke primere.
U sledećem primeru, funkcija sayName
se nalazi unutar objekta me
(dakle, ona je metoda). U ovakvim slučajevima, this
se odnosi na objekat koji sadrži funkciju.
function sayName() { return `Moje ime je ${this.name}` } const me = { name: "Kingsley", sayName: sayName } console.log(me.sayName())
U ovom slučaju, this
je objekat me
, što znači da je izraz this.name
unutar metode sayName
potpuno ekvivalentan sa me.name
.
Drugi način razmišljanja je da će ono što se nalazi levo od funkcije prilikom poziva postati this
. Ovo omogućava ponovnu upotrebu funkcije sayName
u različitim objektima, pri čemu će se svaki put odnositi na potpuno drugačiji kontekst.
Kao što je već pomenuto, this
vraća window
objekat kada se koristi unutar samostalne funkcije, jer je takva funkcija po defaultu vezana za window
objekat:
function talk() { return this } talk()
Pozivanje talk()
je isto kao i pozivanje window.talk()
, i sve što se nalazi levo od funkcije automatski postaje this
.
Važno je napomenuti da se ponašanje ključne reči this
u funkciji menja u JavaScript-ovom „strict mode“ (vraća undefined
). Ovo treba imati na umu prilikom korišćenja UI biblioteka koje koriste „strict mode“ (npr. React).
Korišćenje this
sa Function.bind()
Moguće je da postoje situacije kada ne možete jednostavno dodati funkciju objektu kao metodu (kao u prethodnom primeru).
Možda objekat nije vaš i izvlačite ga iz biblioteke. Objekat je nepromenljiv, tako da ga ne možete direktno menjati. U takvim slučajevima, funkciju i dalje možete izvršiti odvojeno od objekta koristeći metodu Function.bind()
.
U sledećem primeru, funkcija sayName
nije metoda objekta me
, ali ste je ipak vezali pomoću funkcije bind()
:
function sayName() { return `Moje ime je ${this.name}` } const me = { name: "Kingsley" } const meTalk = sayName.bind(me) meTalk()
Koji god objekat prosledite u bind()
biće korišćen kao vrednost za this
pri tom pozivu funkcije.
Ukratko, bind()
možete koristiti na bilo kojoj funkciji i proslediti novi kontekst (objekat). Taj objekat će zameniti značenje this
unutar te funkcije.
Korišćenje this
sa Function.call()
Šta ako ne želite da vratite potpuno novu funkciju, već samo da pozovete funkciju nakon što je povežete sa njenim kontekstom? Rešenje za to je metoda call()
:
function sayName() { return `Moje ime je ${this.name}` } const me = { name: "Kingsley" } sayName.call(me)
Metoda call()
odmah izvršava funkciju umesto da vraća drugu funkciju.
Ako funkcija zahteva parametar, možete ga proslediti preko call()
metode. U sledećem primeru, prosleđujete jezik funkciji sayName()
, kako biste uslovno vraćali različite poruke:
function sayName(lang) { if (lang === "en") { return `Moje ime je ${this.name}` } else if (lang === "it") { return `Io sono ${this.name}` } } const me = { name: "Kingsley" } sayName.call(me, 'en') sayName.call(me, 'it')
Kao što vidite, možete jednostavno proslediti bilo koji broj parametara funkciji kao dodatne argumente metodi call()
.
Metoda apply()
je veoma slična call()
i bind()
. Jedina razlika je u načinu prosleđivanja više argumenata. Kod call()
argumenti se odvajaju zarezima, dok se kod apply()
prosleđuju unutar niza.
Ukratko, bind()
, call()
i apply()
vam omogućavaju da pozivate funkcije sa potpuno drugačijim objektom, bez ikakve direktne veze između njih (tj. funkcija nije metoda tog objekta).
this
unutar konstruktor funkcija
Ako pozovete funkciju sa ključnom reči new
, ona kreira objekat i vraća ga:
function person(name){ this.name = name } const me = new person("Kingsley") const her = new person("Sarah") const him = new person("Jake") me.name her.name him.name
U gornjem kodu ste kreirali tri različita objekta iz iste funkcije. Ključna reč new
automatski stvara vezu između kreiranog objekta i ključne reči this
unutar funkcije.
this
unutar callback funkcija
Callback funkcije se razlikuju od regularnih funkcija. Callback funkcije su funkcije koje prosleđujete drugoj funkciji kao argument, i one se izvršavaju nakon što se glavna funkcija završi sa izvršavanjem.
Ključna reč this
se odnosi na potpuno drugačiji kontekst kada se koristi unutar callback funkcija:
function person(name){ this.name = name setTimeout(function() { console.log(this) }, 1000) } const me = new person("Kingsley")
Nakon jedne sekunde pozivanja konstruktor funkcije person
i kreiranja novog objekta me
, logovaće se window
objekat kao vrednost za this
. Dakle, kada se koristi u callback funkciji, this
se odnosi na window
objekat, a ne na „konstruisani“ objekat.
Postoje dva načina da se ovo popravi. Prvi metod koristi bind()
da poveže person
funkciju sa novo-konstruisanim objektom:
function person(name){ this.name = name setTimeout(function() { console.log(this) }.bind(this), 1000) } const me = new person("Kingsley")
Sa gornjom modifikacijom, this
u callback-u će referencirati isti this
kao i konstruktor funkcija (me
objekat).
Drugi način rešavanja ovog problema u callback funkcijama je korišćenje arrow funkcija.
this
unutar arrow funkcija
Arrow funkcije se razlikuju od regularnih funkcija. Možete vašu callback funkciju pretvoriti u arrow funkciju. Kod arrow funkcija više nije potreban bind()
, jer se automatski vezuju za novo-konstruisani objekat:
function person(name){ this.name = name setTimeout(() => { console.log(this) }, 1000) } const me = new person("Kingsley")
Saznajte više o JavaScript-u
Naučili ste sve o ključnoj reči this
i šta ona znači u svim različitim kontekstima u JavaScript-u. Ako ste novi u JavaScript-u, od velike će vam koristi biti učenje svih osnova JavaScript-a i načina na koji on funkcioniše.