Šta su operatori
Pod operatorom se najčešće podrazumeva simbol koji se koristi kada želimo da izvršimo neku standardnu često korišćenu operaciju kao npr. dodeljivanje vrednosti, poredjenje vrednosti, aritmetičke operacije…
Operatori se mogu shvatiti kao specijalne funkcije koje su za razliku od “običnih funkcija” pisane na “nestadardni način”. Operatori koriste tzv. “infix” notaciju (naziv funkcije se stavlja izmedju dva parametra). Standardni operator prikazan sa “infix” notacijom izgleda ovako:
... operator...
Na sledećem primeru se vidi da postoji suštinaska sličnost operatora sa funkcijom:
1 2 3 4 |
function plus (a, b) { return a+b; } plus(3,4); // Vraća 7 |
Najčešće su u pitanju binarni operatori (operatori koji uzimaju dve vrednosti kao ulaz), mada postoje i unarni operatori koji izvršavaju odredjene operacije samo na jednoj vrednosti:
1 2 3 |
var brojac = 0; brojac++; console.log(brojac); // Vraca: 1 |
Prioritet i Asocijativnost operatora
Asocijativnost operatora je osobina koja govori sa kog kraja se odvija grupisanje (počev od levog ili od desnog kraja). Svaki operator ima svoje pravilo asocijativnosti. U narednojtabeli asocijativnosti i značaja operatora su prikazani operatori i njihova asocijativnost, a poredjanii su prema “važnosti” od “najvažnijeg” ka slabijem.
Važnost | Operator | Naziv operatora | Asocijativnost |
---|---|---|---|
20 | ( … ) | Zagrada za grupisanje | n/a |
19 | … . … | Pristup osobini objekta “dot natation” | s’ leva na desno |
… [ … ] | Pristup osobini objekta “bracket notation” | s’ leva na desno | |
new … ( … ) | new (sa argumentima) | n/a | |
18 | … ( … ) | Pozivanje Funkcije | s’ leva na desno |
new … | new (bez argumenta) | s’ desna na levo | |
17 | … ++ | Postfix Increment | n/a |
… — | Postfix Decrement | n/a | |
16 | ! … | Logical NOT | s’ desna na levo |
~ … | Bitwise NOT | s’ desna na levo | |
+ … | Unary Plus | s’ desna na levo | |
– … | Unary Negation | s’ desna na levo | |
++ … | Prefix Increment | s’ desna na levo | |
— … | Prefix Decrement | s’ desna na levo | |
typeof … | typeof | s’ desna na levo | |
void … | void | s’ desna na levo | |
delete … | delete | s’ desna na levo | |
15 | … ** … | Exponentiation | s’ desna na levo |
14 | … * … | Multiplication | s’ leva na desno |
… / … | Division | s’ leva na desno | |
… % … | Remainder | s’ leva na desno | |
13 | … + … | Addition | s’ leva na desno |
… – … | Subtraction | s’ leva na desno | |
12 | … << … | Bitwise Left Shift | s’ leva na desno |
… >> … | Bitwise Right Shift | s’ leva na desno | |
… >>> … | Bitwise Unsigned Right Shift | s’ leva na desno | |
11 | … < … | Less Than | s’ leva na desno |
… <= … | Less Than Or Equal | s’ leva na desno | |
… > … | Greater Than | s’ leva na desno | |
… >= … | Greater Than Or Equal | s’ leva na desno | |
… in … | in | s’ leva na desno | |
… instanceof … | instanceof | s’ leva na desno | |
10 | … == … | Equality | s’ leva na desno |
… != … | Inequality | s’ leva na desno | |
… === … | Strict Equality | s’ leva na desno | |
… !== … | Strict Inequality | s’ leva na desno | |
9 | … & … | Bitwise AND | s’ leva na desno |
8 | … ^ … | Bitwise XOR | s’ leva na desno |
7 | … | … | Bitwise OR | s’ leva na desno |
6 | … && … | Logical AND | s’ leva na desno |
5 | … || … | Logical OR | s’ leva na desno |
4 | … ? … : … | Conditional | s’ desna na levo |
3 | … = … | Assignment | s’ desna na levo |
… += … | |||
… -= … | |||
… **= … | |||
… *= … | |||
… /= … | |||
… %= … | |||
… <<= … | |||
… >>= … | |||
… >>>= … | |||
… &= … | |||
… ^= … | |||
… |= … | |||
2 | yield … | yield | s’ desna na levo |
yield* … | yield* | s’ desna na levo | |
1 | … … | Spread | n/a |
0 | … , … | Comma / Sequence | s’ leva na desno |
“undefined” & “null” kao učesnici poredjenja!?
Poredjenje undefined sa brojevima ili string-om UVEK vraća FALSE:
1 2 3 4 5 6 7 8 9 10 |
undefined > 5 //false undefined < 5 // false undefined == 0; //false undefined == ""; //false undefined > 0; //false undefined < 0; //false undefined > -1; //false undefined < 1; //false undefined >= 0; //false undefined <= 0; //false |
Poredjenje sa “null” je krajnje nelogično, u najmanju ruku čudno i bez nekog pravila te treba izbegavati da uopšte dodje do takvih poredjenja tj. sprečiti pojavljivanje null u poredjenju!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
null > 5 //false null < 5 //true null == 0; //false null == ""; //false null > 0; //false null < 0; //false null >= 0; //true null <= 0; //true null > -1; //true null < 1; //true |
A ako su medjusobno u poredjenju
1 2 3 4 5 6 |
undefined == null //true null == undefined //true null > undefined //false null <= undefined //false null < undefined //false |
Specifičnost “==” operatora
Operator “==” tzv. “slaba jednakost” poredi dva operanda prema njihovoj vrednosti i vraća logičku vrednost TRUE ili FALSE.
Da li će se vršiti implicitna konverzija tipova, zavisi od toga koji tipovi se medjusobno porede. Ako zbog poredjenja dve vrednosti različitog tipa dodje do implicitne konverzije jednog od njih, taj postupak se vrši prema pravilima za konverziju, nakon čega sledi poredjenje. U sledećoj tabeli su zapisani svi slučajevi izmedju svih mogućih tipova za poredjenje sa operatorom “==”
Operand B | |||||||
---|---|---|---|---|---|---|---|
Undefined | Null | Number | String | Boolean | Object | ||
Operand A | Undefined | true | true | false | false | false | false |
Null | true | true | false | false | false | false | |
Number | false | false | A === B | A === ToNumber(B) | A === ToNumber(B) | A == ToPrimitive(B) | |
String | false | false | ToNumber(A) === B | A === B | ToNumber(A) === ToNumber(B) | A == ToPrimitive(B) | |
Boolean | false | false | ToNumber(A) === B | ToNumber(A) === ToNumber(B) | A === B | ToNumber(A) == ToPrimitive(B) | |
Object | false | false | ToPrimitive(A) == B | ToPrimitive(A) == B | ToPrimitive(A) == ToNumber(B) | A === B |
Primer
Kada se porede ova dva tipa pravilo je da se string konvertuje u broj
1 |
console.log("40" == 40); // => 40 == 40 vraca TRUE |
Primer
Ovaj slučaj često pravi probleme jer neka pravila u JS-u mogu da navedu na pogrešan zaključak. Pravilo koga se treba pridržavati je da se kod poredjenja logička vrednost se konvertuje u broj, pogledaj više ovde.
1 |
console.log("50" == TRUE); // => 50==1 vraca FALSE |
Primer
Prema ES5 ukoliko se porede undefined == null sa operatorom “labava jednakost” UVEK se dobija TRUE.
1 2 |
undefined == null; //TRUE null == udefined; //TRUE |
Primer
Kada se poredi undefined/null sa nekim primitivnim tipom podataka UVEK vraća FALSE.
1 |
console.log(2 == null); // Vraca False |
Česta zabluda je da se pri poredjenju undefined/null i nekog drugog primitivnog tipa podataka očekuje konverzija u FALSE pa zatim u nulu, i da je nakon toga moguće poredjenje.
Specifičnost operatora && i ||
Kada jedan ili čak oba operanda nisu logičkog tipa pri korišćenju operatora && i || dolazi do konverzije u logički tip prema pravilima za konverziju, ali nakon razrešenja uslova ne vraćaju logičku vrednost, već vraćaju vrednost jednog od dva operanda. Šta će da bude razultat uslova se odredjuje prema sledećim pravilima:
- Za operator || nakon konverzije “ne logičkog” tipa u logički pri razrešenju uslova važi:
ukoliko je krajnje rešenje uslova operatora TRUE on vraća vrednost prvog operanda, a u slučaju FALSE vraća vrednost drugog operanda.
1234console.log(3 || true); //rezultat je 3console.log(3 || false); //rezultat je 3console.log(true || 3); //rezultat je TRUEconsole.log(false || 3); //rezultat je 3 - Za operator && nakon konverzije “ne logičkog” tipa u logički pri razrešenju uslova važi:
ukoliko je krajnje rešenje uslova operatora TRUE vraća vrednost drugog operanda i obrnuto.
1234console.log(3 && true); //rezultat je trueconsole.log(3 && false); //rezultat je falseconsole.log(true && 3); //rezultat je 3console.log(false && 3); //rezultat je false
Primeri
Nadovezani uslovi
1 2 3 4 5 |
var a = 42; var b = "foo"; var c = [1,2,3]; a && b || c // Rezultat je : "foo" |
Objašnjenje:
Uvažavajući prioritete operatora koji su korišćeni, logičko “i” ima prednost nad logičkim “ili”, pa prethodni izraz može da se konvertuje u:
1 |
(a && b) || c |
Za odredjivanje uslova u zagradi se vrši implicitna konverzija tipova u logički tip:
1 |
(TRUE && TRUE) || c |
Rešenje uslova je TRUE, pa stoga po pomenutom pravilu za TRUE, operator “&&” vraća vrednost drugog operanda, pa sredjeni izraz ovako izgleda:
1 |
"foo" || [1,2,3] |
Ponovo se vrši implicitna konverzija u logički tip:
1 |
TRUE || TRUE |
Rešenje ovog uslova je TRUE, pa stoga prema pravilu operator || vraća vrednost prvog operanda.
Nadovezano dodeljivanje
1 2 3 |
var a = 2, b = 3, c = 4; a = b = c; //Vraća: 4 |
Objašnjenje:
Osobina asocijativnosti kod operatora dodeljivanja “=” je s’desna na levo stoga prethodni izraz bi moga da se prikaže grupisan ovako:
1 |
a = (b = c); |
Stoga će prvo biti dodeljena vrednost 4 promenjivoj b, nakon čega izraz postaje:
1 |
a = 4; |
3.) Nadovezano poredjenje
1 |
3 < 2 < 1 // Vraća TRUE |
Objašnjenje:
Asocijativnost operatora “<" je s’ leva na desno pa izraz nakon grupisanja izgleda ovako:
1 |
(3 < 2) < 1 |
Rešavanjem prve operacije dobija se logička vrednost FALSE, pa izraz izgleda
1 |
FALSE < 1 |
Pri poredjenju dva elementa različitog tipa dolazi do implicitne konverzije FALSE u broj “0” nakon čega izraz izgleda:
1 |
0 < 1 |
Što vraća rezultat TRUE
Kod primera
function plus (a, b) {
return a+b;
}
plus(3,4); – ne reaguje na konzoli i ne vraca 7. Vasa greska u koracima
nego tek kada se ukuca
console.log(plus(3,4)); vraca 7
Nije greška, ova funkcija nije zamišljena da štampa rezultat u konzoli već kao što piše da vrati vrednost (eng. “return”).
Tako vraćena vrednost se kasnije npr. može dodeliti nekoj promenjivoj:
var a = plus(3,4);
i onda se može sa njom može raditi šta god želimo pa čak i da se štampa u konzoli:
console.log(a);
Profesionalnost na nivou.Svaka čast!
Hvala