Prioritet operatora u JavaScriptu

Ako želimo da na ispravan način kreiramo izraze u JavaScriptu (kao i u bilo kom drugom programskom jeziku), moramo se upoznati sa redosledom izvršavanja operacija, odnosno sa "snagom" operatora. Redosled operacija će biti predstavljen u sledećoj tabeli, od najjačih, ka najslabijim.

PrioritetGrupaOperatoriAsocijativnostDostupnost
0Operator grupisanja()-
1Pristup elementu objektaobj.x
obj[x]
udesno ▶
Kreiranje instance sa argumenatimanew f(a,b)-
Poziv funkcijef()udesno ▶
Opciono ulančavanjeobj?.xudesno ▶FF74, C80
2Kreiranje instance bez argumenatanew x◀ ulevo
3Sufiksno uvećanje i umanjenjex++
x--
-
4Logička negacija!x◀ ulevo
Negacija bitova~x◀ ulevo
Znak broja+x
-x
◀ ulevo
Prefiksno uvećanje i umanjenje++x
--x
◀ ulevo
Ispitivanje tipatypeof x◀ ulevo
Brisanje elementa objektadelete obj.x◀ ulevo
Poništavanje vrednostivoid x◀ ulevo
Razrešavanje promisaawait x◀ ulevoFF52, C55
5Stepenovanjex ** y◀ ulevoFF52, C52
6Aritmetičke operacije višeg prioritetax * y
x / y
x % y
udesno ▶
7Aritmetičke operacije nižeg prioritetax + y
x - y
udesno ▶
8Pomeranje bitovax << y
x >> y
x >>> y
udesno ▶
9Relacioni operatorix < y
x > y
x <= y
x >= y
udesno ▶
Svojstvo objektax in yudesno ▶
Konstruktor objektax instanceof yudesno ▶
10Jednakost i nejednakostx == y
x != y
x === y
x !== y
udesno ▶
11AND nad bitovimax & yudesno ▶
12XOR nad bitovimax ^ yudesno ▶
13OR nad bitovimax | yudesno ▶
14Logička konjunkcijax && yudesno ▶
15Logička disjunkcijax || yudesno ▶
16Postojanje vrednostix ?? y◀ ulevoFF72, C80
17Uslovni operatorx ? y : z◀ ulevo
18Operatori dodelex = y
x += y
x -= y
x *= y
x /= y
x %= y
x <<= y
x >>= y
x >>>= y
x &= y
x |= y
x ^= y
◀ ulevo
19Vrednost generatorayield x
yield* x
◀ ulevo
20Operator odvajanjax, yudesno ▶

*) Dostupnost označava verzije web čitača (FF - Firefox i C - Chrome) za operatore koji su uvedeni nakon poslednjih verzija dostupnih na Windows XP sistemu.

Kada želimo da se određene operacije izvše pre drugih (iako se to ne bi desilo prema redosledu), isto kao u matematici, koristimo zagrade. Zagrade su "najjače" i operacije koje se nalaze unutar njih uvek imaju prednost.

Asocijativnost

Asocijativnost operacija se odnosi na smer evaluacije izraza, ili prostim jezikom, to je smer u kome se razrešavaju operacije u izrazu. To naravno važi samo ako su operatori istog prioriteta, i ako redosled operacija nije promenjen grupisanjem unutar zagrada.

Hajde da prvo pogledamo kako funkcioniše asocijativnost udesno na primeru operacije oduzimanja. Izračunajmo vrednost sledećeg izraza:

10 - 3 - 2 = ? 10 - 3 - 2 = // najpre se od 10 oduzima 3 što daje 7 7 - 2 = // a onda se od 7 oduzima 2 5

Logično, prvo se računa 10 - 3, što daje rezultat 7, a onda se računa razlika tog 7 i 2 i konačni rezultat je 5.

Pravilo asocijativnosti udesno nam govori da se prvo razrešava oduzimanje sa leve strane, pa se onda ide udesno ka poslednjem oduzimanju. Za razliku od npr. sabiranja, ovde redosled jeste bitan. Koji rezultat bismo dobili kada bi za oduzimanje važila asocijativnost ulevo?

10 - 3 - 2 = ? 10 - 3 - 2 = // ako krenemo sa desne strane, 3-2 daje vrednost 1 10 - 1 = // od 10 oduzimamo 1 9 (NEISPRAVNO!)

U takvom slučaju bi se prvo izračunala razlika 3 - 2, a onda bi se od 10 oduzelo tako dobijeno 1, što bi dalo neispravan rezultat 9.

Hajde sada da napravimo sličan primer, ali sa operacijom stepenovanja koja zaista ima asocijativnost ulevo. U ovom primeru računamo rezultat izraza koji bi se matematički zapisao kao 323.

3 ** 2 ** 3 = ? 3 ** 2 ** 3 = // najpre se vrši stepenovanje sa desne strane, 2 na kub je 8 3 ** 8 = // zatim se računa osmi stepen broja 3 6561

Pošto je stepenovanje operacija koja ima asocijativnost ulevo, polazi se od stepenovanja sa desne strane. Dakle prvo se računa stepenovanje 23 što daje 8, a onda se računa stepenovanje 38.

Kada bismo pokušali da računamo od leve strane, dobili bismo neispravan rezultat:

3 ** 2 ** 3 = ? 3 ** 2 ** 3 = // kretanjem s leva, računali bismo prvo 32 što daje 9 9 ** 3 = // a onda bismo 9 podigli na kub 729 (NEISPRAVNO!)

Naravno, prioritet operatora "nadjačava" asocijativnost, što znači da se prvo izračunavaju operacije koje imaju jači prioritet, a tek onda, kada ostanu operacije istog prioriteta, gleda se asocijativnost. Ne brinite - ne možemo doći u dvosmislenu situaciju da se ne zna koja operacija se najpre izvršava, pošto se nikada ne dešava da operatori istog prioriteta imaju različitu asocijativnost.

Primer

Hajde da pogledamo sledeći primer i da pokušamo da rastumačimo šta će biti njegov rezultat i zašto.


  var x = 12, y = 8, z = 2;
      
  var rez = y += x + y < 15 ? 1 : 0 - z;
  
  // dakle, prema prioritetu, u ovom izrazu najjače operacije su 
  // sabiranje i oduzimanje koje se evaluiraju s leva na desno
    rez = y += x + y < 15 ? 1 : 0 - z;
    rez = y += 20 < 15 ? 1 : 0 - z;
  // zatim se vrši operacija poređenja
    rez = y += 20 < 15 ? 1 : -2;
  // sledeći na redu je ternarni operator izbora
    rez = y += false ? 1 : -2;
  // na kraju dolaze dva operatora dodele, koji se evaluiraju s desna na levo
    rez = y += -2;
    rez = 6;
  

Proverite i sami kako ovo funkcioniše...

js-oper-redosled-sr
  1. MDN, Operator Precedence
  2. S. Stefanov, K.C. Sharma (2013): Object-Oriented JavaScript, 2nd.ed, Packt Publishing, Birmingham
  3. Addy Osmani, Learning JavaScript Design Patterns
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.