6 min read

Az operátorok - első rész

Az operátorok - első rész

Bizonyára találkoztál már az operátor szóval a hétköznapi életben, azonban itt nem munkához kapcsolódó fogalom lesz tisztázva, hanem, hogy mik is azok az operátorok JS esetében.

Pongyola, de érthető megfogalmazásban: az operátor olyan szimbólum vagy keyword (kulcsszó), mely valamilyen műveletet hajt végre a paraméterével (vagy paramétereivel).

Pár operátor már megjelent a korábbi cikkekben csak éppen nem lettek nevén nevezve, hogy ők bizony operátorok, sőt pár operátor típus is (unary, binary, ternary).
Azt már most szeretném leszögezni, hogy a cikkben nem lesz az összes operátor felsorolva, mert rengeteg van, de az összes csoporthoz fogok írni példákat (így is ketté kell szednem a cikket, mert túl hosszú lenne és nem szeretném ha belealudnál a végébe). Szintaktikájuk lehet:

  • operator operand
  • operand operator (azaz  bizonyos esetekben az operandus megelőzi az operátort)
  • operand1 operator operand2
  • és van egy speciális eset, mely majd a helyén be lesz mutatva

Az operátorokat JS esetében 10 csoportba sorolhatjuk, (melyek között van átfedés) . Kezdjük azokkal amik már kicsit ismerősek, majd bővítsük ki őket a többivel:

Unary operators

Egy olyan operátor, melynek egyetlen operandusa (operand) vagy más szóval paramétere van, és azzal végez műveletet. Például:

  • typeof operand vagy typeof (operand): korábbi cikkben már találkoztál vele, segítségével az operandus típusát tudod meg
  • delete operand: segítségével egy object property-jét tudod törölni. A delete operátorról később lesz még szó

A bitműveleteknél találkoztál a NOT operátorral ami szintén unary operátor, azonban ezt egy másik csoportban fogom bemutatni, ahova logikailag jobban passzol (és akkor meg is van magyarázva, hogy miért van átfedés a csoportok között).

Ternary operator

A szemfülesebb angolosoknak most talán feltűnt, hogy singular-t használtam. Nem véletlenül, hiszen ebben a "csoportban" csak egy operátor foglal helyet, amelyet úgy hívunk, hogy conditional operator (feltétel(es) operátor) és a szintakszisa elég speciális (és akkor itt van a helye annak amit fentebb írtam):

condition ? value1 : value2

Értelmezni pedig úgy kell, hogy: ha a condition (feltétel) igaz, akkor az operátor értéke value1, ha pedig hamis, akkor value2
A programozási gyakorlatban ezt az operátort jellemzően változó értékadásánál szoktuk használni, de használata nincs csak és kizárólag erre limitálva.
Példa a használatra:

var signSymbol = myNumber < 0 ? "-" : "+";

Az erősebb matekosok bizonyára most zúzták be a monitort egy féltéglával, hiszen itt egy blogger, aki valahol az elején kiemelte, hogy a szabatos fogalmazás a programozásban mennyire fontos és ennek ellenére itt van ez a "féligazság", hogy a nullánál kisebb számok negatívak míg a többi meg pozitív, holott minden igaz szívvel rendelkező, magára valamit is adó ember tudja, hogy a nulla az neutrális szám. Oké, megadom magam, pontosítsuk picit:

var singSymbol = myNumber < 0 ? "-" : myNumber > 0 ? "+" : "";

Mi történt itt? Tulajdonképpen két ternary operator egymásba ágyazása. Ha nem teljesült az első feltétel (a szám nem kisebb nullánál, ugrunk a : utáni részre), akkor jön egy újabb feltételvizsgálat, ami megnézi, hogy nagyobb-e nullánál. Ha igen, akkor pozitív szám, ha nem, akkor már csak egy lehetőség maradt, hogy a szám 0 (hiszen se nem kisebb és se nem nagyobb nála) és ebben az esetben nem kell semmilyen előjelszimbólumot használnunk és az üres stringet rendeljuk a signSymbol változónkhoz.

Arithmetic operators

Matematikai műveletek operátorai tartoznak ebbe a csoportba ám a négy alapműveleten (+, -, * és /) kívül (amiket szerintem be sem kell mutatni, hiszen matematika órán megtanították veled) három nagyon fontos operátort mindenképpen meg kell említsek:

Remainder: esetleg modulus néven is találkohatsz vele; egy egész számot ad vissza mely a két operandus osztásának maradéka. Szintaktikája:  operand operator operand
Példa:
42 % 20 (melynek eredménye: 2)

Increment: az operátor a ++ amit elhelyezhetünk az operandus előtt (ekkor az operator operand szintaktika él: ++x) illetve után is (operand operator szintaktika: x++). Mindkét esetben az operandus növelése történik 1-el, de van egy lényegi különbség a kettő között ami csak akkor lényeges, ha szeretnénk az operátor által visszaadott értéket használni (ez pl. egy typeof esetében triviális, hiszen mi másért kérdeznénk le a típust, de pl. egy delete esetében számunkra a lényeg, hogy töröltük a property-t az objectből és itt a növelés esetén sem biztos, hogy érdekel minket mit ad vissza az operátor). Ez az operátor visszaadja az x növelés előtti értékét ha a pre-increment formát (++x) használtuk, illetve visszaadja az x növelés utáni értékét ha a post-increment formát (x++) használtuk. Eldönthetjük, hogy kezdünk-e valamit ezzel a visszaadott értékkel (pl. hozzárendeljük egy változóhoz) vagy megelégszünk azzal a ténnyel, hogy az operandusunk értéke 1-el nőtt. Létezik a másik irány is, ami a decrement és nem meglepő módon a -- reprezentálja és csökkenti az operandus értékét, egyebek tekintetében ugyanúgy viselkedik mint a növelés.

Unary plus: egy unary operator, amely az operandust konvertálja (átalakítja) szám típusúvá (ha sikerül neki!). Szintakszisa: operator operand: +x
Odakiabáltam zárójelbe, hogy "ha sikerül neki". Nyílván "Béla"-t nem tudjuk számmá konvertálni, ha mégis megpróbáljuk, akkor a jól a ismert NaN (Not a Number) fogjuk kapni, ami valójában igaz is, hiszen Béla nem egy szám. Létezik a nagyon hasonló unary negation is amit a - jellel tudunk ugyanígy hasznáni, ami azon kívül, hogy megcsinálja a kovertálást még negatív előjelűre is váltja nekünk.
Érdemes talán megemlíteni, hogy nem csak szöveget lehet számmá alakítani, hanem pl. boolean (mely lehet true vagy false) típust is. Ha booleant konvertálunk számmá akkor a true-ból 1 a false-ból pedig 0 lesz (valójában pont így is van tárolva a háttérben egy boolean típusú változó).

Assignment operators

Hozzárendelési operátor. A hozzárendelést többször emlegettem már, példa is lett bemutatva, úgyhogy egyet ezek közül már biztosan ismersz, még ha akkor nem is tudtad, hogy az egy operátor. Nézzünk pár hozzárendelési operátort:

Assignment: egyszerű hozzárendelés, legtöbbször ezt használjuk ebből a csoportból. Szintaktikája az operand1 operator operand2
Példa:

x = y

Értelmezése: x legyen egyenlő y-al. A fenti példában az x és az y a két operandus, míg az = jel az operátor.

Az összes többi, ebbe a csoportba tartozó operátor úgynevezett compound (összetett) operátor és az egyszerű hozzárendelést bővíti ki valamilyen extra funkcióval. Nézzünk ezekre is pár példát operandusként megtartva az x-et és az y-t:

Addition assignment: x += y. Rövidített formája az x = x + y formának. Matematikusok most biztos meg is oldják magukban a képletet és elkönyvelik magukban, hogy ez csak akkor lehetséges, ha y nulla. Kérlek ne tedd, ez nem matematikai képlet, ezt így kell értelmezni: x új értéke legyen egyenlő x jelenlegi értékével plusz az y értéke.

Az összeadáson kívül a többi matematikai alapműveletre is létezik operátor (subtraction: -=, multiplication: *=, division: /=) és értelmezésük (a megfelelő szó kihelyettesítésével) ugyanaz mint az addition assignmentnek.

String operator

A stringek összefűzésére (összeadására) a + operátort használjuk, ezt már láthattad az előző cikkben. Emlékeztető példa:

console.log("Hello, " + "World!");

Itt az ideje tisztázni egy másik részét a gyengén típusos és az erősen típusos kifejezéseknek, melynek ismerete nélkül az összehasonlító operátorok ismertetése nem lenne pontos.

Vegyük az alábbi esetet:

var a = "4";
var b = 2;
var c = a + b;
var d = b + a;
var e = +a + b;
console.log(c, d, e);

A fenti példának látszólag semmi értelme, hiszen hogyan lehet összeadni egy stringet egy számmal, de talán a 5. sorban látható unary plus operátor megkongatott némi vészharangot benned.

A gyengén típusos nyelveknél a változók implicit módon átkonvertálhatók másik típusúvá, míg az erősen típusos nyelveknél ezt nekünk explicit módon külön kérnünk kell, megerősítve ezzel a fordítót abban, hogy valóban ezt akarjuk csinálni.
Tehát a fenti példában amikor megpróbáljuk a harmadik sorban a "4"-hez (string) hozzáadni a 2-t (number), akkor az értelmező felfedezi, hogy ez nem lehetséges és úgymond közös nevezőre hozza őket (string) és elvégzi az összeadást a string operátorral és megkapjuk az eredményt: "42".
Ha azt gondolnád, hogy a következő sorban a 4-et fogja nekünk átkonvertálni az értelmező számmá és így végzi el a műveletet, akkor ki kell, hogy ábrándítsalak, ugyanúgy a szám lesz stringre konvertálva és így az eredmény "24". Amelyik kutya erősebb... Nade mi vagyunk az erősebbek, hiszen mi is megmondhatjuk az értelmezőnek (explicit módon(!) az unary plus segítségével), hogy legyen szíves a stringet számmá alakítani és úgy végezze el az összeadást (ez látható az 5. sorban). Ha ezt nem tesszük meg, akkor feltételezi, hogy string-ként próbálod összeadni őket.

Az erősen típusos nyelveknél nem opcionális az, hogy megmondjuk, hogy típuskonverziót szeretnénk végrehajtani, hanem kötelező (a típuskonverziók nyelvenként eltérően valósíthatók meg, egy példa a sok közül str(b), ami a b változót szöveggé alakítja). Ha elfelejtjük, akkor hibaüzenetet fogunk kapni, hogy a két típuson az adott műveletnek nincs értelme.

Könnyen belátható, hogy a gyengén típusos nyelveknél talán kevesebbet kell gépelnünk, de a hiba lehetősége is jelentősen megnő a "nem kért" típuskonverziók miatt.


A többi operátor a következő cikkben lesz tárgyalva.

Mit tanultál ebben a leckében?

  • megtanultad, hogy az operátor olyan szimbólum, amely valamilyen műveletet hajt végre az operanduasain
  • megtanultad, hogy milyen szintakszisai lehetnek az operátoroknak
  • megnéztünk 5-öt a 10 csoportból és mindegyikre láttál példákat
  • megtudtad, hogy a gyengén típusos nyelvek – bár neked is van kontrollod a típuskonverziók felett – implicit módon elvégzik a típuskonverziót helyetted