A matematikából sok összehasonlító operátort ismerünk.
A JavaScriptben ezek így íródnak:
- Nagyobb/kevesebb, mint:
a > b
,a < b
. - Nagyobb/kevesebb, mint vagy egyenlő:
a >= b
,a <= b
. - Egyenlő:
a == b
, figyeljünk arra, hogy a dupla egyenlőségjel==
az egyenlőségi vizsgálatot jelenti, míg a szimplaa = b
a hozzárendelést. - Nem egyenlő. A matematikában a jelölés
≠
, de a JavaScriptbena != b
-nek írják.
Ebben a cikkben többet megtudunk a különböző típusú összehasonlításokról, arról, hogy a JavaScript hogyan végzi őket, beleértve a fontos sajátosságokat is.
A végén találsz egy jó receptet a “JavaScript furcsaságokkal” kapcsolatos problémák elkerülésére.
Boolean az eredmény
Minden összehasonlító operátor boolean értéket ad vissza:
-
true
– azt jelenti, hogy “igen”, “helyes” vagy “az igazság”. -
false
– azt jelenti, hogy “nem”, “rossz” vagy “nem az igazság”.
Például:
alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)
Az összehasonlítás eredménye ugyanúgy hozzárendelhető egy változóhoz, mint bármely érték:
let result = 5 > 4; // assign the result of the comparisonalert( result ); // true
String összehasonlítás
Azért, hogy egy string nagyobb-e egy másiknál, a JavaScript az úgynevezett “szótári” vagy “lexikográfiai” sorrendet használja.
Más szóval a karakterláncokat betűről betűre hasonlítjuk össze.
Például:
alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true
A két karakterlánc összehasonlításának algoritmusa egyszerű:
- Mindkét karakterlánc első karakterét összehasonlítjuk.
- Ha az első karakterlánc első karaktere nagyobb (vagy kisebb), mint a másik karakterláncé, akkor az első karakterlánc nagyobb (vagy kisebb), mint a második. Végeztünk.
- Máskülönben, ha mindkét karakterlánc első karaktere megegyezik, hasonlítsuk össze a második karaktereket ugyanígy.
- Ismételjük meg a két karakterlánc végéig.
- Ha mindkét karakterlánc azonos hosszúsággal végződik, akkor egyenlőek. Ellenkező esetben a hosszabb karakterlánc a nagyobb.
A fenti első példában az 'Z' > 'A'
összehasonlítás már az első lépésben eredményre jut.
A második összehasonlítás 'Glow'
és 'Glee'
több lépést igényel, mivel a karakterláncokat karakterenként hasonlítjuk össze:
-
G
megegyezikG
. -
l
megegyezikl
. -
o
nagyobb, minte
. Itt álljunk meg. Az első karakterlánc nagyobb.
A fent megadott összehasonlítási algoritmus nagyjából megegyezik a szótárakban vagy telefonkönyvekben használtal, de nem teljesen ugyanaz.
Az esetek például számítanak. A "A"
nagybetű nem egyenlő a "a"
kisbetűvel. Melyik a nagyobb? A kisbetűs "a"
. Miért? Mert a kisbetűnek nagyobb indexe van a JavaScript által használt belső kódolási táblázatban (Unicode). Ennek konkrét részleteire és következményeire a Strings fejezetben még visszatérünk.
Eltérő típusok összehasonlítása
A különböző típusú értékek összehasonlításakor a JavaScript az értékeket számokká alakítja.
Például:
alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1
Boolean értékek esetén true
1
lesz, false
pedig 0
.
Például:
alert( true == 1 ); // truealert( false == 0 ); // true
Ez lehetséges, hogy egyszerre:
- Két érték egyenlő.
- Az egyik
true
mint boolean, a másikfalse
mint boolean.
Egyikük például:
let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!
A JavaScript szempontjából ez az eredmény teljesen normális. Az egyenlőségi ellenőrzés az értékeket a numerikus konverzió segítségével konvertálja (így lesz "0"
-ból 0
), míg az explicit Boolean
konverzió más szabályrendszert használ.
Szigorú egyenlőség
A szabályos ==
egyenlőségi ellenőrzéssel van egy probléma. Nem tud különbséget tenni 0
és false
között:
alert( 0 == false ); // true
Az üres karakterlánc esetében ugyanez történik:
alert( '' == false ); // true
Ez azért történik, mert a különböző típusú operandusokat az ==
egyenlőségi operátor számokká alakítja. Az üres karakterlánc, akárcsak a false
, nullává válik.
Mit tegyünk, ha a 0
-t szeretnénk megkülönböztetni a false
-től?
A szigorú egyenlőségi operátor ===
típuskonverzió nélkül ellenőrzi az egyenlőséget.
Más szóval, ha a
és b
különböző típusúak, akkor a === b
azonnal false
-et adja vissza anélkül, hogy megpróbálnánk konvertálni őket.
Kipróbáljuk:
alert( 0 === false ); // false, because the types are different
Létezik egy !==
“szigorú nem egyenlőségi” operátor is, amely analóg a !=
-val.
A szigorú egyenlőségi operátort kicsit hosszabb leírni, de nyilvánvalóvá teszi, hogy mi történik, és kevesebb teret hagy a hibáknak.
Visszahasonlítás null és undefined
Van egy nem intuitív viselkedés, amikor a null
vagy undefined
értékeket más értékekkel hasonlítjuk össze.
Szigorú egyenlőségi ellenőrzésnél===
Ezek az értékek különbözőek, mert mindegyik más típusú.
alert( null === undefined ); // false
Nem szigorú ellenőrzésnél==
Van egy speciális szabály. Ez a kettő “édes pár”: egyenlőek egymással (a ==
értelmében), de más értékkel nem.
alert( null == undefined ); // true
Matematikai és egyéb összehasonlításokhoz< > <= >=
null/undefined
számokká alakítjuk: null
0
lesz, míg undefined
NaN
.
Most lássunk néhány vicces dolgot, ami történik, ha ezeket a szabályokat alkalmazzuk. És ami még fontosabb, hogyan ne essünk velük csapdába.
Furcsa eredmény: nulla vs. 0
Hasonlítsuk össze a null
számot egy nullával:
alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true
Matematikailag ez furcsa. Az utolsó eredmény szerint “null
nagyobb vagy egyenlő nullával”, tehát a fenti összehasonlítások egyikében true
-nek kell lennie, de mindkettő hamis.
Az ok az, hogy az ==
egyenlőségi ellenőrzés és az > < >= <=
összehasonlítások eltérően működnek. Az összehasonlítások a null
-t számmá alakítják, és 0
-nek tekintik. Ezért igaz a (3) null >= 0
és hamis a (1) null > 0
.
Az undefined
és null
==
egyenlőségi ellenőrzése viszont úgy van definiálva, hogy mindenféle átalakítás nélkül egyenlőek egymással, és nem egyenlőek semmi mással. Ezért (2) null == 0
hamis.
Egy összehasonlíthatatlan meghatározatlan
Az undefined
értéket nem szabad összehasonlítani más értékekkel:
alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)
Miért nem szereti annyira a nullát? Mindig hamis!
Azért kapjuk ezeket az eredményeket, mert:
- A
(1)
és(2)
összehasonlításokfalse
-et adnak vissza, mertundefined
átváltozikNaN
-re, ésNaN
egy speciális numerikus érték, amely minden összehasonlításnálfalse
-et ad vissza. - Az
(3)
egyenlőségi ellenőrzésfalse
-et ad vissza, mertundefined
csaknull
,undefined
és semmilyen más értékkel nem egyenlő.
A problémák elkerülése
Miért mentünk át ezeken a példákon? Mindig emlékeznünk kell ezekre a sajátosságokra? Nos, nem igazán. Valójában ezek a trükkös dolgok idővel fokozatosan megszokottá válnak, de van egy biztos módszer arra, hogy elkerüljük a velük kapcsolatos problémákat:
- A szigorú egyenlőség
===
kivételével mindenundefined/null
-ös összehasonlítást kivételes óvatossággal kezeljünk. - Ne használjunk
>= > < <=
összehasonlítást olyan változóval, amely lehetnull/undefined
, hacsak nem vagyunk igazán biztosak abban, hogy mit csinálunk. Ha egy változónak lehetnek ilyen értékei, külön ellenőrizd őket.
Summary
- Az összehasonlító operátorok egy bólus értéket adnak vissza.
- A stringeket betűről betűre hasonlítjuk össze a “szótári” sorrendben.
- A különböző típusú értékek összehasonlításakor számokká konvertálódnak (a szigorú egyenlőségi ellenőrzés kizárásával).
- A
null
ésundefined
értékek egyenlőek==
egymással, és nem egyenlőek semmilyen más értékkel. - Vigyázzunk, ha olyan összehasonlításokat használunk, mint a
>
vagy<
olyan változókkal, amelyek esetenkéntnull/undefined
lehetnek. Anull/undefined
külön-külön történő ellenőrzése jó ötlet.