Deo zbornika Napredni Javaskript
Prototipski lanac
Prvo ćemo ispitati kako svojstvo prototype funkcioniše, da bismo shvatili u čemu je razlika između sopstvenog svojstva i svojstva prototipa.
Upotrebićemo konstruktor funkciju da napravimo novi objekat:
function Junak(ime, rasa) {
this.ime = ime
this.rasa = rasa
}
Junak.prototype.energija = 100
const gimli = new Junak('Gimli', 'patuljak')
console.log(gimli.ime)
console.log(gimli.energija)
Kada pokušamo da pristupimo nekom svojstvu objekta (na primer gimli.ime
), JavaScript virtuelna mašina proverava sva svojstva objekta da bi pronašla svojstvo pod tim nazivom, nakon čega vraća njegovu vrednost.
Šta se dešava ako pokušamo da pristupimo svojstvu energija
? JavaScript virtuelna mašina pregleda sva svojstva objekta gimli
i ne nalazi svojstvo energija
. Zatim, virtuelna mašina identifikuje prototype
konstruktorske funkcije, i ako tu nađe svojstvo energija
, vraća njegovu vrednost.
Vrednostima prototipa takođe možemo direktno pristupiti. Svaki objekat ima svojstvo constructor
, koje predstavlja referencu na njegovu konstruktorsku funkciju. Na primer:
gimli.constructor // Junak
Dakle, sinonim za Junak.prototype.energija
bio bi:
gimli.constructor.prototype.energija // 100
Pošto svaki objekat ima konstruktor, a prototype
je objekat, on takođe mora da ima konstruktor, koji sadrži svojstvo prototype
, što čini prototipski lanac. Na kraju prototipskog lanca je ugrađeni objekat Object()
, element najvišeg nivoa. To znači da ćemo, ako upotrebimo metod gimli.toString()
za objekat koji nema svoj metod toString()
, na kraju dobiti ugrađeni metod objekta toString()
:
gimli.toString() // "[object Object]"
Sopstveno svojstvo vs. svojstvo prototipa
Šta će se desiti ako objekat ima svoje svojstvo i ako prototip, takođe, ima svojstvo sa istim nazivom? Onda sopstveno ima prednost nad svojstvom prototipa. Na primer:
function Junak(ime) {
this.ime = ime
}
Junak.prototype.ime = 'Spartak'
const legolas = new Junak('Legolas')
console.log(legolas.ime)
Možemo proveriti da li je svojstvo definisano, tako što ćemo upotrebiti metod hasOwnProperty()
:
legolas.hasOwnProperty('ime') // true
Ako izbrišemo svojstvo ime
sa objekta, onda će se koristiti svojstvo prototipa:
delete legolas.ime // true
legolas.ime // "Spartak"
legolas.hasOwnProperty('ime') // false
Možemo da koristimo metod hasOwnProperty()
da bismo istražili odakle potiče određeno svojstvo. Na primer, možemo da vidimo odakle potiče metod toString()
:
legolas.toString() // "[object Object]"
legolas.hasOwnProperty('toString') // false
legolas.constructor.hasOwnProperty('toString') // false
legolas.constructor.prototype.hasOwnProperty('toString') // false
Object.hasOwnProperty('toString') // false
Object.prototype.hasOwnProperty('toString') // true
Literatura
- Ved Antani, Stojan Stefanov, Objektno-orjentisan JavaScript, Beograd, 2017.