Call, apply i bind metode u JavaScriptu
Tags: javascript, webdev
Published: 2023-03-06 20:06:14

## Šta možete pročitati ovdje?

- Uvod i ključna riječ `this`.
- Metoda `.call()`.
- Metoda `.apply()`.
- Metoda `.bind()`.

---

### Uvod i ključna riječ `this`


U drugim izričito objektno orijentisanim jezicima ključna riječ `this` se uvijek odnosi na trenutnu instancu klase. U JavaScriptu `this` se ponaša malo drugačije. Vrijednost riječi `this` zavisi od toga kako/gdje je funkcija pozvana.

U svrhu ovog teksta jednostavno ćemo reći da se `this` u JavaScriptu odnosi na objekat koji je pozvao metodu. Vizuelno će to biti objekat koji se nalazi lijevo od tačke prilikom pozivanja metode.

Recimo npr. da imamo objekat `osoba` sa određenim svojstvima i jednom metodom koja koristi svojstva iz tog objekta.


![example of this in basic object in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tl1owvntd2j4l752cw81.png)


Dakle, pozvali smo metodu `reciKoSi` iz objekta `osoba`. Objekat se nalazi lijevo od tačke i na njega se odnosi ključna riječ `this`. Zato metoda `reciKoSi` ima pristup svojstvima `ime` i `godine` iz objekta `osoba`. Ovo je očekivano ponašanje.

Međutim, šta ako pokušamo da dodijelimo ovu metodu kao vrijednost nekoj varijabli?

![assign method from object in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4p0pdlowk5jekpdt8l5.png)


Ovo je potpuno validna JavaScript sintaksa, ali problem je nastupio kada smo pokušali da je pozovemo. Zašto ova metoda nema pristup svojstvima `ime` i `godine`? Zato što je nismo pozvali na `osoba` objektu. Pozvali smo je bez reference na bilo koji objekat. To automatski znači da se `this` odnosi na globalni `window` objekat, a taj objekat nema svojstva `ime` i `godine`.

Upravo ovo je jedna od situacija zbog kojih kažemo da referenca ključne riječi `this` zavisi od toga kako je pozvana funkcija.

Ovakvo ponašanje ključne riječi `this` je jedan od razloga zbog kog je `this` izvor velike zabune u JavaScriptu, pa se njeno korištenje često i izbjegava.

Kao što sam već rekao ovo je samo jedan od razloga. Ključna riječ `this` je izuzetno složena tema sama za sebe i više nego dovoljna da bude tema jednog odvojenog teksta. No, u svrhu današnje teme dovoljno je shvatiti da se `this` odnosi na objekat koji je pozvao metodu, odnosno vizuelno objekat koji se nalazi lijevo od tačke prilikom pozivanja metode.

---

### Metoda `.call()`

Jedna od tri veoma važne metode u JavaScriptu u objektno orijentisanom pristupu je `.call()` metoda.

Recimo npr. da imamo dva objekta `osoba1` i `osoba2`.


![example of two basic objects in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nll2qkmb1pvcvy0r8lpq.png)

Objekat `osoba1` ima metodu `reciKoSi` kojom može da se predstavi tako što će reći ime i godine. Ali šta ako bilo gdje u aplikaciji želimo da se neka druga osoba predstavi. Objekat `osoba2` nema metodu `reciKoSi`, ali želimo da je iskoristimo. Da bi izbjegli dupliciranje koda tako što bi samo kopirali istu metodu `reciKoSi` u objekat `osoba2` itd., itd. sa bilo kojim drugim objektom kojem bi mogla koristiti da funkcija, tu na snagu stupa `.call()` metoda.

Sintaksa je takva da ćemo jednostavno pozvati `reciKoSi` metodu iz objekta `osoba1` i onda vezati `.call` metodu. Prvi argument je objekat na koji želim da se odnosi ključna riječi `this`. Objekat kojim mijenjamo kontekst za `this`.


![example of .call method in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yhevmhjizhl28jnrihua.png)

Šta se ovdje dogodilo? Pozvali smo `.call` metodu, ali sa drugim kontekstom. Sa objektom `osoba2` kao argumentom promijenili smo kontekst za ključnu riječ `this`, odnosno promijenili smo na šta se odnosi `this`. Rekli smo pozovi `reciKoSi` metodu, ali `this` će da se odnosi na objekat `osoba2`.

Pored prvog argumenta koji mijenja kontekst za `this`, `.call` metoda može da dobije i bilo koji broj drugih argumenata, baš kao i svaka druga funkcija. Ti argumenti će biti uneseni poslije objekta jedan za drugim.

Recimo npr. da u našem primjeru objekti imaju svojstvo `omiljeniSlatkiši`, koje je predstavljeno kao niz stringova. Metoda za dodavanje novih omiljenih slatkiša će biti `dodajSlatkiš`.


![example of .call method in JavaScript with arguments](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eexnr4n6yhgvdpeh0dha.png)

Poslije objekta smo unijeli sve argumente koje metoda `dodajSlatkiš` ima na raspolaganju.

---


### Metoda `.apply()`

Metoda `.apply()` je identična po ponašanju kao i `.call` metoda. Jedina razlika je u argumentima koji se unose poslije objekta.


![example of .apply method in JavaScript with arguments](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n8q0yoeow7lcdjet456l.png)

Dakle, sintaksa je slična kao i kod `.call()` metode. Jedina razlika je što se argumenti poslije objekta unose u jednom nizu, umjesto jedan za drugim kao što je u `.call()` metodi. Kao i kod `.call()` metode možemo navesti koliko god želimo argumenata.


---

### Metoda `.bind()`

Slično kao i u prethodna dva slučaja u `.bind()` metodi možemo da promijenimo kontekst za `this`.

Razlika je u tome što `bind` metoda neće odmah pozvati metodu, što je slučaj ko `call` i `apply` metoda. Bind funkcioniše tako što će vratiti funkciju, sa datim kontekstom i parametrima/argumentima, koja može kasnije biti pozvana.

Dakle ovo neće imati nikakav uticaj na objekat `osoba2`:

![example of callign bind method in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gsocz2rz1smk474xij4g.png)

Ovdje funkcija/metoda `dodajSlatkiš` nije pozvana. Međutim, možemo referencu na ovu metodu staviti u neku varijablu za kasnije pozivanje.

![example of store bind method for later use in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/feeew24wzqnd9n4t4kzj.png)

Ili možda čak i primjer gdje argumente dodajemo prilikom pozivanja funkcije `dodajIskriSlatkiš`.

![example of an alternative approach to bind arguments in JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bze3gv75v99l0wz2wz5i.png)

Ova ova primjera će za donijeti isti rezultat.

Dakle, `.bind()` poziv nam je dao na raspolaganje funkciju sa `osoba2` kontekstom i parametrima. Tu vrijednost smo proslijedili varijabli `dodajIskriSlatkiš` da bi je kasnije mogli pozvati. Iako izgleda da smo pozvali funkciju `dodajIskriSlatkiš` iz globalnog objekta, ona nije preuzela njegov kontekst, nego ima kontekst koji smo joj naveli u `.bind()` metodi.

Upravo `.bind` metoda je rješenje za naš problem sa početka ovog teksta kada smo izgubili kontekst za objekat `osoba` prilikom proslijeđivanja njegove metode `reciKoSi` u varijablu za kasnije pozivanje.

Neke druge teme o kojim sam pisao na temu JavaScripta, web developmenta, možete pronaći [ovdje](https://dev.to/bslaven).