Šta je objekat?

Definicija i svojstva

objekat

Objekat je jedan od glavnih tipova podataka u JavaScript-u, prikazan u vidu “neuredjene liste podataka u obliku parova ključ/vrednost.
U JavaScript-u postoji konvencija da se svojstvo (tj. key/value par) koje za vrednost ima funkciju zove “metoda”. Prema toj konvenciji svojstava objekta su ustvari atributi tog objekta (specifične stvari vezane baš za taj objekat), dok su metode akcije koje može da izvršava taj objekat.

Objekat je tipa “reference”, što znači da se pri dodeljivanju nekoj promenjivi objekat ne kopira nego se pointer te promenjive povezuje za mesto u memoriji gde je smešten taj objekat. Ukoliko kreiramo objekat preko izraza kao što je konstruktor ili literal, taj objekat je različit od svakog drugog objekta, jer se smešta na novo mesto u memoriji.
Provera da li su dva objekta jednaka se može izvršiti preko operatora “===”, koji upoređuje objekte po referenci. Da bi dva objekta bila jednaka nije dovoljno da imaju isti sadržaj! Dva objekta su jednaka samo ako imaju isti identitet i nalaze se na istom mestu u memoriji.

Kada dve promenjive ukazuju na isti objekat, tj. kada njihovi pointeri ukazuju na isto mesto u memoriji, promene koje izvršimo nad objektom preko jedne promenjive se reflektuju i na drugu promenjivu.

Deskriptori svojstva

Svako svojstvo (eng. properties) u objektu ima četri atributa koje ga definišu, ti atributi se zovu deskriptori svojstva (eng. descriptor properties):

  1. value

    Kroz ovaj deskriptor se definiše vrednost svojstva

  2. writable

    Kada je ovaj deskriptor setovan na false nije moguće menjanje vrednosti svojstva:

    Ukoliko koristimo “use strict” i striktni režim svaki pokušaj menjanja vrednosti se završava greškom.

  3. enumerable

    Ovaj deskriptor odredjuje da li će se svojstvo pojavljivati u nekim operacijama nabrajanja svojstava ili ne, kao što je “for..in” petlja.

  4. configurable

    Kada se ovaj deskriptor setuje na false, to je jednosmerna ulica bez povratka, jer tada više ne možemo da menjamo svojstva preko metode “defineProperty()”. Ovaj deskriptor setovan na false čak sprečava brisanje svojstva sa naredbom “delete“. U narednom primeru pokušaj brisanja se završava neuspešno:

Da li je u JavaScript-u sve objekat?

Često se može čuti da je sve u JavaScript-u objekat, ova izjava nije bez osnova jer postoji puno naznaka koje upućuju da je sve objekat. Medjutim to nije u potpunosti istina, u narednom delu ću pokušati da prodjem kroz sve tipove i objasnim koji jesu a koji nisu tipa objekat.

Da li su nizovi objekat?

Nizovi jesu tipa objekat ali su to specifični objekti. Oni čuvaju vrednosti numerički indeksirane. Čak je moguće dodeliti vrednost preko nekog ključa kao kod običnog objekta ali se to ne preporučuje, jer dodavanjem nekog imenovanog svojstva nizu se ne menja dužina niza izmerena preko svojstva lenght.izraz typeof vraća ‘objekat’

Da li su funkcije objekat?

Kod funkcija je malo komplikovanjije one su tipa funkcije, ali su i istovremeno i objekat. Ovo je moguće jer su funkcije u JavaScriptu su “first class citizen”, a to znači da je funkcija entitet koji podržava sve operacije dostupne drugim tipovima, jer može da se ponaša kao bilo koja druga vrsta entiteta i kod koje ne postoji restrikcija kako se kreira ili koristi. U slučaju JavaScript-a to podrazumeva da funkcija ima sve osobine drugih primitiva, pa je možemo proslediti kao argument, možemo je vratiti (return) kao vrednost iz neke druge funkcije ili je možemo dodeliti nekoj promenjivoj. Pored nabrojanih osobina funkcije imaju i sve osobine objekata, ali zbog toga nisu “običan” objekat već su više od objekta tj. specijalni nadtip objekta. One pored svih osobina objekta ima i dodatu semantiku za pozivanje (eng. invoke). Pošto je funkcija više od objekta, izraz typeof ne vraća tip objekat nego tip function.

Da li su “primitivi” tipa objekat?

U JavaScript-u pored objekta kao specifičnog tipa podataka postoje još i tzv. primitivi (“prosti primarni tipovi podataka”). Primitivni tipovi nisu objekat! Primitivi za razliku od objekta su “immutable” i porede se preko vrednosti (eng.value). U primitivne tipove spadaju:

  • string
  • number
  • boolean
  • undefined
  • null
  • symbol

Još jedan dokaz da su primitivi drugačiji tipovi podataka od tipa objekat se vidi kroz sledeće izraze:

Ipak totalni haos i zbrku pravi činjenica da je:

Smatra se da je prethodni izraz jedan od najpoznatijih bug-ova u JavaScript-u. Smatra se da ovaj bug verovatno nikada neće biti rešen, jer je za to već kasno, citiraću: “Too much code on the Web relies on the bug and thus fixing it would cause a lot more bugs!”

Objekti ugradjeni u JS core prave zbrku

Naglasio sam da primitivi nisu “objekat”, ali glavnu zbrku pravi činjenica da postoje objekti ugradjeni u core javascript-a čija su imena ista kao imena prostih primitiva (mada nazivi počinju sa velikim slovom!):

  • String
  • Number
  • Boolean

NAPOMENA:
Pored “nesrećnih” naziva za ugradjene objekte dodatnu pometnju pravi automatska konverzija primitivnog tipa u njegov “parnjak” objekat. Ovo konverzija se dešava kad na primitivni tip nadovežemo neku od metoda ugradjenog objekta tzv. “parnjaka”. Kompajler automatski konvertuje prost tip u njegov “parnjak” objekat, nakon čega je dozvoljeno koristiti sve metode tog objekta.

Primer

U ovom primeru nad primitivom tipa “string” se poziva metoda objekta. Kompajler automatski privreno “pretvara” primitiv tipa “string” u objekat tipa String, nakon čega su mu dostupne sve metode ugradjenog objekta, pa i metoda lenght:

Metode vezane za svojstva objekta

Utvrdjivanje postojanja svojstva i metoda

  1. hasOwnPropery()
  2. operator in

a) hasOwnPropery()

Metodom “hasOwnPropery()” se ispituje da li odredjeni objekat (bez objekata u protoytpe lancu) ima neko svojstvo:

b) Operator “in”

Za ispitivanje svih objekta u prototype lancu se koristi operator in. Sa ovim operatorom se ispituje da li sam objekat ima neko svojstvo, ali se takodje proveravaju i svi objekti koji delegiraju svojstva u prototype lancu.

NAPOMENA:
Pored ova dva načina često se može videti naredni pristup:

Ovaj način vraća isti rezultat kao operator “in” (sva svojstva u prototype lancu”), medjutim ovakav pristup se ne preporučuje jer najsporiji.

Iteracija svojstava

Postoje tri ugradjena načina da se izlistaju svojstva u JavaScript objektu:

a) Petlja “for..in”

Ova petlja prolazi kroz sva svojstva (koja imaju setovano enumerable: true) objekta i celog prototype lanca.

b) Object.keys()

Ova metoda vraća niz svih ključeva datog objekta (nisu uključeni i objekti prototype lanca)

c) Object.getOwnPropertyNames()

Ova metoda vraća niz svih ključeva objekta pa čak i onih svojstava kod kojih je deskriptor enumerable: false

Provera iterativnosti svojstva

Metodom “propertyIsEnumerable()” ispituje da li je deskriptor svojstva enumerable setovano na vrednost true.

Izlistavanje deskriptora nekog svojstva

Atribute svojstva tzv. deskriptore svojstva nekog objekta dobijamo koristeći metodu “Object.getOwnPropertyDescriptor()”:

Primer

Definisanje i izmena deskriptora

Ukoliko je deskriptor svojstva configurable setovan na false nije moguće je dodavati novo svojstvo ili ažurirati postojeća svojstva sa metodom Object.defineProperty():

Primer

Ovako ažuriran objekta ima za vrednost svojstav “a” broj 3.

Pravljenje objektne konstante

Pravljenje objektne konstante koja se ne može izmeniti, niti izbrisati kao svojstvo odredjenog objekta se vrši setovanjem odredjenih deskriptora na sledeći način writable: false, configurable: false:

Primer

Sprečavanje dopunjavanja objekta

Ako želimo da sprečimo dodavanje novih svojstva nekom objektu koristimo metodu “Object.PreventExtension()”

Zapečaćivanje objekta

Metoda “Object.seal()” uzima objekat i za njega poziva prethodnu metodu preventExtension(), i takodje postavlja deskriptor configurable na false (=> configurable: false + sprečeno dodavanje novih svojstva). Rezultat ove metode je da se objektu ne mogu dodati nova svosjtva, kao i da se postojeća svojstva ne mogu izbrisati, niti da se mogu promeniti drugi deskriptori osim deskriptora “value”

Zamrzavanje objekta

Metoda “Object.freeze()” preuzima postojeći objekat, i za njega poziva metodu “Object.seal()” i svim svojstvima objekta menja vrednost descriptora “writable” na false (=> writable: false, configurable: false + sprečeno dodavanje novih svojstva). Ova metoda omogućuje najviši nivo nepromenjivosti objekta.

Get i Set metode

Praksa je da se pristup privatnim svojstvima ostvaruje uz korišćenje specijalnih metoda tzv. “get-era” i “set-era”.

Primer

Sa ovakim mehanizmom, svaki put kada želimo da ostvarimo interakciju sa svojstvom “punoIme ostvarujemo ili sa “get_punoIme()” ili “set_punoIme()” metodom.

Pogledajte slične članke...

Podelite:

Ostavite komentar