Svojstva i metodi JavaScript objekta

U ovom tekstu ćemo naučiti nešto više o radu sa svojstvima JavaScript objekata. Počećemo sa najjednostavnijim stvarima kao što je korišćenje svojstva - čitanje i dodela vrednosti. Zatim ćemo naučiti da JavaScript objekti dosta podsećaju na asocijativne nizove pošto se svojstva mogu zadavati i kao ključevi. Naučićemo i kako da proverimo da li svojstvo postoji u objektu, kao i da pobrojimo svojstva objekta. Konačno, naučićemo i kako da uklonimo svojstvo iz objekta.

Kao što smo videli u tekstu o kreiranju objekata, kada jednom već imamo objekat, u njega lako dodajemo novo svojstvo (property) - prostim navođenjem naziva svojstva i vrednosti.

objekat.svojstvo = vrednost;

Ako svojstvo do tada nije postojalo, biće kreirano. Ako je postojalo, jednostavno će dobiti novu vrednost.

Bitno je da zapamtite - objekti imaju samo svojstva. Ono što zovemo metodima su i dalje samo svojstva koja su reference na funkcije.

Svojstva kao ključevi

Svojstva JavaScript objekta više liče na ključeve asocijativnog niza u nekim drugim programskim jezicima, nego na "prava" svojstva. Zaista, mogu da sadrže i razne dodatne znakove (!, #, $, %, &, *, @), kao i cifre i razmake.

Najvažnije ograničenje je vezano za način pozivanja svojstva. Npr. svojstvo koje u nazivu ima razmake jednostavno ne možemo zadati posle tačke. Pri navođenju objektnog literala, ovakve "čudne" nazive svojstava zadajemo kao stringove. Dakle, svojstvo je moguće definisati na bilo koji od navedena tri načina:

var obj = { ... svojstvo: vrednost, "svojstvo": vrednost, 'svojstvo': vrednost, ... };

Ono što ne možemo da uradimo, je da navodimo svojstvo objekta u obliku stringa, posle tačke:

obj.svojstvo // ispravno obj."svojstvo" // pogrešno obj.'svojstvo' // pogrešno

Srećom, postoji način da se i to reši, navođenjem naziva svojstva kao stringa unutar uglastih zagrada:

obj["svojstvo"] obj['svojstvo']

Najbolje od svega je što ovo čak i ne moraju da budu string literali, već i promenljive ili čak celi izrazi:

var prom = "svojstvo"; // naziv svojstva je u nekoj promenljivoj ... obj[prom] // pozivamo svojstvo preko te promenljive

Dodavanje metoda je potpuno isto - navodimo svojstva kao što bismo naveli bilo koje druge reference na funkcije.

objekat.metod = function() {}; objekat["metod"] = function() {};

Primer zadavanja svojstava

Lako je ako su svojstva objekta reči, međutim, šta ako nam je baš stalo da se nazivi svojstava sastoje iz cifara? Pogledajte šta jeste, a šta nije dozvoljeno.


  var a = {12:99, "23":98, '34':97, web:"study"};

  var xx = 34;
  
  a[23] = 345;     // broj kao ključ
  a["12"] = 456;   // string kao ključ
  a[xx] = 789;     // promenljiva kao ključ

  a.12 = 88;       // neispravno
  a."12" = 88;     // neispravno
  
  a.xx = 88;       // nepravilno - dodaje novo svojstvo "xx"
  

Greška u nazivu svojstva

Evo primera koji ilustruje grešku u zadavanju vrednosti svojstva. Želimo da HTML elementu označenom kao "pasus" promenimo boju pozadine. Ovo je nešto što ćemo učiti u okviru Web DOM programiranja, ali za sada možemo da kažemo da metod getElementById() objekta document vraća referencu na traženi elemenat. Tako "uhvaćen" elemenat ima podobjekat style koji sadrži svojstva koja pokrivaju celokupan inline CSS elementa.


  document.getElementById("pasus").style.backgroundcolor = "#def";
  

Konkretno svojstvo koje predstavlja boju pozadine je backgroundColor. Kao što znate, JavaScript je osetljiv na velika i mala slova, što znači da navedeno svojstvo nije ispravno.

Međutim, JavaScript neće prijaviti grešku, već će smatrati da je to neko novo svojstvo koje nameravamo da dodamo u objekat style. Tako će biti kreirano novo svojstvo backgroundcolor, u koje će biti smeštena zadata vrednost i - ništa. Program će normalno nastaviti da se izvršava, neće biti prijavljena nikakava greška, samo ni pozadina neće promeniti boju.

Provera svojstva u objektu

U određenim slučajevima želimo da proverimo da li objekat poseduje neko svojstvo ili ne. Ovakvu proveru koristimo kod objekata koji nisu potpuno pod našom "kontrolom" - npr. ako se objekat izgrađuje automatski na osnovu podataka sa servera ili aktivnosti korisnika. U nekim situacijama korstimo proveru da li postoji neko svojstvo kako bismo identifikovali sam objekat.

Ima boljih i lošijih načina. Lenji programeri obično koriste prost upit:

if (objekat.svojstvo)... ... ili objekat.svojstvo ? nešto : nešto drugo

Ovo u dobrom broju slučajeva funkcioniše - ako svojstvo ne postoji, rezultat će biti null što se tumači kao false. Međutim, problem nastaje ako svojstvo postoji, ali ima vrednost null, 0, false... što sve daje negativan odgovor na pitalicu, zbog čega se program ponaša kao da svojstvo ne postoji.

Ovde ćemo se upoznati sa dve mnogo bolje alternative. Prva je operator in, koji koristimo kako bismo utvrdili da li neki element (svojstvo ili metod) postoji u objektu. Naziv elementa se zadaje kao string.

svojstvo in objekat

Rezultat ove operacije je true ako se svojstvo/metod može pozvati za objekat. U ovo spadaju i svojstva koja su nasleđena - pretraživanje se vrši "naviše" kroz ceo prototipski lanac.

Drugi način je korišćenje metoda hasOwnProperty() koji vraća true ako traženo svojstvo/metod postoji u objektu.

objekat.hasOwnProperty(svojstvo)

Ovo je metod koji nasleđuju svi objekti (pogađate, "poreklo" mu je od objekta object). Razlika u odnosu na korišćenje operatora in je što se na ovaj način proveravaju samo svojstva i metodi koji pripadaju tom objektu, ne i ona koja su nasleđena.

Primer ispitivanja svojstva u objektu

Pogledajmo neke primere:


  var obj = {data:50};
  obj[123] = false;
  
  "data" in obj       // true
  "x" in obj          // false
  123 in obj          // true
  "123" in obj        // true
  "toString" in obj   // true - ovaj metod nasleđuje svaki objekat

  var obj = {data:50};
  obj[123] = false;
  
  obj.hasOwnProperty("data")       // true
  obj.hasOwnProperty("x")          // false
  obj.hasOwnProperty(123)          // true
  obj.hasOwnProperty("toString")         // false - ne radi za nasleđena svojstva
  obj.hasOwnProperty("hasOwnProperty")   // false - naravno i on sam je nasleđen :)

Nabrajanje svojstava

Ovo je osobina koja definiše "pristupačnost" svojstvu. Ne u smislu da li se svojstvu može pristupiti, već da li se svojstvo može automatski "nabrojati" (enumerable). JavaScript ima nekoliko načina za nabrajanje svojstava objekta, a za neke od njih se svojsto može čak i isključiti iz "nabrajanja".

Inače, kada kreiramo objekat, sva svojstva koja mu dodeljujemo jesu nabrojiva, što znači da ćemo morati dodatno da se pomučimo kako bismo postigli da svojstvo ne bude nabrojivo.

Ako svojstvo nije nabrojivo, neće biti "pronađeno" tokom for-in, Object.keys() i JSON.stringify().

Prvi način da nabrojimo svojstva objekta je korišćenje metoda getOwnPropertyNames() objekta Object. Ovaj metod se koristi nad nekim objektom i vraća niz naziva svih sopstvenih svojstava objekta:

Object.getOwnPropertyNames(objekat)

Kao rezultat ćemo dobiti niz stringova koji predstavljaju nazive svojstava zadatog objekta. Dobijaju se sva svojstva, bez obzira da li su nabrojiva, ali samo ako pripadaju tom objektu. Ovim metodom se ne dobijaju nasleđena svojstva.

Veoma slično funkcioniše metod keys objekta Object. Takođe vraća niz naziva svih sopstvenih svojstava objekta, ali samo nabrojivih:

Object.keys(objekat)

Znači ovde isto nećemo dobiti nasleđena svojstva.

JavaScript ima poseban tip ciklusa - for-in, koji služi za enumeraciju, odnosno "prolazak" kroz sva nabrojiva svojstva - sopstvena i nasleđena:

for (naziv in objekat) ...

U svakoj iteraciji ciklusa, promenljiva koju navodimo kao naziv dobija naziv nekog svojstva iz objekta objekat. Kao što je rečeno, to će biti ne samo sopstvena, već i nasleđena svojstva, ali samo ona koja su nabrojiva.

Primer enumeracije svojstava


  // osnovni objekat
  var osnovni = {jedan:1, dva:2, tri:3};
  
  // nasleđeni objekat
  var obj = Object.create(osnovni);
  obj.cetiri = 4;
  obj.pet = 5;

  // enumeracija svih sopstvenih svojstava    
  var niz = Object.getOwnPropertyNames(obj);
  console.log(niz);  // ["cetiri", "pet"]

  // enumeracija svih sopstvenih nabrojivih svojstava    
  var niz1 = Object.keys(obj);
  console.log(niz1);  // ["cetiri", "pet"]

  // enumeracija svih nabrojivih svojstava  
  for (var svojstvo in obj) {
    console.log(svojstvo)  // "cetiri", "pet", "jedan", "dva", "tri"
  }

Pre nego što počnete da se bunite kako među getOwnPropertyNames() i keys() nema razlike, sačekajte da naučimo kako da neko svojstvo proglasimo nenabrojivim.

Brisanje svojstva

Na kraju ćemo naučiti i kako da uklonimo neko svojstvo iz objekta. Za ovo se koristi poseban operator delete, iza koga zadajemo objekat i svojstvo koje se briše.

delete objekat.svojstvo delete objekat["svojstvo"]

Ne zaboravite, moguće je obrisati samo svojstva koja direktno pripadaju objektu. Nasleđena svojstva možemo obrisati samo u prototipskom objektu.

Primer za uklanjanje svojstva

U prvom primeru možemo videti da možemo ukloniti samo sopstvena svojstva objekta, ne i nasleđena.


  // osnovni objekat
  var osnovni = {jedan:1, dva:2, tri:3};
  
  // nasleđeni objekat
  var obj = Object.create(osnovni);
  obj.cetiri = 4;
  obj.pet = 5;

  // sada brišemo neka svojstva
  delete obj.pet;    // brisanje sopstvenog svojstva - RADI
  delete obj.dva;    // brisanje nasleđenog svojstva - NE RADI

  // enumeracija svih nabrojivih svojstava  
  for (var svojstvo in obj) {
    console.log(svojstvo)  // "cetiri", "jedan", "dva", "tri"
  }

U drugom primeru, vidimo da možemo obrisati svojstva i kada im pristupamo kao da su ključevi (u uglastim zagradama).


  var obj = {jedan:1, dva:2, tri:3, cetiri:4, pet:5};

  console.dir(obj);  // "jedan", "dva", "tri", "cetiri", "pet"

  // prolazimo kroz sva svojstva
  for (var svojstvo in obj) {
    if (obj[svojstvo] > 2) {     // ako je vrednost svojstva veća od dva...
      delete obj[svojstvo];      // uklanja ga iz objekta
    }
  }
  console.dir(obj);  // "jedan", "dva"
  1. S. Stefanov, K.C. Sharma (2013): Object-Oriented JavaScript, 2nd Edition, Packt, Birmingham
  2. Mozilla Developer Network, Object Initializer
Svi elementi sajta Web'n'Study, osim onih za koje je navedeno da su u javnom vlasništvu, vlasništvo su autora i ne smeju se koristiti, u celosti ili delimično bez pismenog odobrenja autora. To uključuje tekstove, slike, ilustracije, animacije, prateći grafički materijal i programski kod.
Ovaj sajt koristi tehnologiju kolačića (cookies). Detaljnije o tome možete pročitati u tekstu o našoj politici privatnosti.