Z matematiky známe mnoho operátorů porovnávání.
V JavaScriptu se zapisují takto:
- Větší/menší než:
a > b
,a < b
. - Větší/menší než nebo rovná se:
a >= b
,a <= b
. - Rovná se:
a == b
, všimněte si, že dvojité znaménko rovnosti==
znamená test rovnosti, zatímco jednoduchéa = b
znamená přiřazení. - Není rovno. V matematice je zápis
≠
, ale v JavaScriptu se zapisuje jakoa != b
.
V tomto článku se dozvíte více o různých typech porovnávání, o tom, jak je JavaScript provádí, včetně důležitých zvláštností.
Na konci najdete dobrý recept, jak se vyhnout problémům souvisejícím s „podivnostmi JavaScriptu“.
Boolean je výsledek
Všechny operátory porovnávání vracejí logickou hodnotu:
-
true
– znamená „ano“, „správně“ nebo „pravda“. -
false
– znamená „ne“, „špatně“ nebo „není pravda“.
Například:
alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)
Výsledek porovnání lze přiřadit proměnné stejně jako jakoukoli jinou hodnotu:
let result = 5 > 4; // assign the result of the comparisonalert( result ); // true
Pro zjištění, zda je řetězec větší než jiný, používá JavaScript takzvané „slovníkové“ nebo „lexikografické“ uspořádání.
Jinými slovy, řetězce se porovnávají písmeno po písmenu.
Například:
alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true
Algoritmus pro porovnání dvou řetězců je jednoduchý:
- Porovnejte první znak obou řetězců.
- Jestliže je první znak z prvního řetězce větší (nebo menší) než znak druhého řetězce, pak je první řetězec větší (nebo menší) než druhý. Hotovo.
- Jestliže jsou první znaky obou řetězců stejné, porovnejte stejným způsobem i druhé znaky.
- Pak opakujte postup až do konce obou řetězců.
- Pokud oba řetězce končí stejně dlouhé, pak jsou si rovny. V opačném případě je delší řetězec větší.
V prvním příkladu výše se porovnáním 'Z' > 'A'
dostaneme k výsledku v prvním kroku.
Druhé porovnání 'Glow'
a 'Glee'
potřebuje více kroků, protože řetězce se porovnávají znak po znaku:
-
G
je stejný jakoG
. -
l
je stejný jakol
. -
o
je větší neže
. Zde se zastavte. První řetězec je větší.
Výše uvedený porovnávací algoritmus zhruba odpovídá tomu, který se používá ve slovnících nebo telefonních seznamech, ale není úplně stejný.
Například záleží na velikosti písmen. Velké písmeno "A"
se nerovná malému písmenu "a"
. Které z nich je větší? Malé písmeno "a"
. Proč? Protože malý znak má větší index ve vnitřní kódovací tabulce, kterou používá JavaScript (Unicode). Ke konkrétním podrobnostem a důsledkům se vrátíme v kapitole Řetězce.
Při porovnávání hodnot různých typů JavaScript převádí hodnoty na čísla.
Například:
alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1
Pro logické hodnoty se z true
stane 1
a z false
0
.
Například:
alert( true == 1 ); // truealert( false == 0 ); // true
Může se stát, že současně:
- Dvě hodnoty jsou si rovny.
- Jedna z nich je
true
jako boolean a druhá jefalse
jako boolean.
Například:
let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!
Z hlediska JavaScriptu je tento výsledek zcela normální. Kontrola rovnosti převádí hodnoty pomocí číselného převodu (proto se z "0"
stane 0
), zatímco explicitní převod Boolean
používá jinou sadu pravidel.
Strict equality
Pravidelná kontrola rovnosti ==
má problém. Nedokáže rozlišit 0
od false
:
alert( 0 == false ); // true
To samé se děje s prázdným řetězcem:
alert( '' == false ); // true
Děje se tak proto, že operandy různých typů jsou operátorem rovnosti ==
převedeny na čísla. Prázdný řetězec se stejně jako false
stane nulou.
Co dělat, když bychom chtěli odlišit 0
od false
?
Striktní operátor rovnosti ===
kontroluje rovnost bez typové konverze.
Jinými slovy, pokud jsou a
a b
různých typů, pak a === b
okamžitě vrátí false
bez pokusu o konverzi.
Zkusíme to:
alert( 0 === false ); // false, because the types are different
Existuje také operátor „striktní nerovnosti“ !==
analogický k !=
.
Striktní operátor rovnosti je trochu delší na zápis, ale je z něj zřejmé, o co jde, a ponechává méně prostoru pro chyby.
Při porovnávání null
nebo undefined
s jinými hodnotami dochází k neintuitivnímu chování.
Pro přísnou kontrolu rovnosti ===
Tyto hodnoty se liší, protože každá z nich je jiného typu.
alert( null === undefined ); // false
Pro nepřísnou kontrolu ==
Existuje zvláštní pravidlo. Tyto dvě hodnoty tvoří „sladkou dvojici“: vzájemně se rovnají (ve smyslu ==
), ale ne jiné hodnotě.
alert( null == undefined ); // true
Pro matematické a jiné porovnávání se < > <= >=
null/undefined
převádí na čísla: null
se stane 0
, zatímco undefined
se stane NaN
.
Nyní se podívejme na některé zábavné věci, které se stanou, když použijeme tato pravidla. A co je důležitější, jak se s nimi nedostat do pasti.
Podivný výsledek: nula vs. 0
Srovnejme null
s nulou:
alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true
Maticky je to zvláštní. Poslední výsledek říká, že „null
je větší nebo rovno nule“, takže v jednom z výše uvedených porovnání to musí být true
, ale obě jsou nepravdivá.
Důvodem je, že kontrola rovnosti ==
a porovnání > < >= <=
fungují jinak. Porovnání převádí null
na číslo a zachází s ním jako s 0
. Proto je (3) null >= 0
pravdivé a (1) null > 0
nepravdivé.
Naproti tomu kontrola rovnosti ==
pro undefined
a null
je definována tak, že bez jakýchkoli konverzí se rovnají navzájem a nerovnají se ničemu jinému. Proto je (2) null == 0
nepravdivý.
Nesrovnatelná nedefinovaná
Hodnota undefined
by se neměla porovnávat s jinými hodnotami:
alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)
Proč se jí tak nelíbí nula? Vždycky false!
Tyto výsledky dostaneme, protože:
- Porovnání
(1)
a(2)
vracífalse
, protožeundefined
se převede naNaN
aNaN
je speciální číselná hodnota, která vracífalse
pro všechna porovnání. - Kontrola rovnosti
(3)
vracífalse
, protožeundefined
se rovná pouzenull
,undefined
a žádné jiné hodnotě.
Vyhnout se problémům
Proč jsme tyto příklady probírali? Měli bychom si tyto zvláštnosti stále pamatovat? No, ne tak docela. Ve skutečnosti se s těmito záludnostmi časem postupně seznámíme, ale existuje solidní způsob, jak se problémům s nimi vyhnout:
- K jakémukoli porovnání s
undefined/null
kromě striktní rovnosti===
přistupujte mimořádně opatrně. - Nepoužívejte porovnání
>= > < <=
s proměnnou, která může býtnull/undefined
, pokud si nejste opravdu jisti, co děláte. Pokud proměnná může mít tyto hodnoty, zkontrolujte je zvlášť.
Souhrn
- Operátory porovnávání vracejí logickou hodnotu.
- Řetězce se porovnávají písmeno po písmenu ve „slovníkovém“ pořadí.
- Při porovnávání hodnot různých typů se tyto hodnoty převedou na čísla (s vyloučením přísné kontroly rovnosti).
- Hodnoty
null
aundefined
se navzájem rovnají==
a nerovnají se žádné jiné hodnotě. - Při porovnávání jako
>
nebo<
buďte opatrní s proměnnými, které mohou být občasnull/undefined
. Kontrolanull/undefined
zvlášť je dobrý nápad.