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 = ba 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:
-
GmegegyezikG. -
lmegegyezikl. -
onagyobb, 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
truemint boolean, a másikfalsemint 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, ésNaNegy 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, mertundefinedcsaknull,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/undefinedlehetnek. Anull/undefinedkülön-külön történő ellenőrzése jó ötlet.