Z matematiky známe mnoho srovnávacích operátorů.
V JavaScriptu se zapisují takto:
- Větší/menší než:
a > b
,a < b
. - Větší/menší nebo rovno:
a >= b
,a <= b
. - Rovno:
a == b
, poznamenejte si prosím znak dvojité rovnosti==
znamená test rovnosti, zatímco jedena = b
znamená úkol. - Nerovná se:V matematice je zápis
≠
, ale v JavaScriptu je zapsán jakoa != b
.
V tomto článku se dozvíme více o různých typech srovnání, o tom, jak je JavaScript vytváří, včetně důležitých zvláštností.
Na konci najdete dobrý recept, jak se vyhnout problémům souvisejícím s „vychytávkami v JavaScriptu“.
Výsledkem je logická hodnota
Všechny operátory porovnání vrací booleovskou 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 jakékoli hodnotě:
let result = 5 > 4; // assign the result of the comparison
alert( result ); // true
Porovnání řetězců
Aby se zjistilo, zda je řetězec větší než jiný, používá JavaScript takzvané „slovníkové“ nebo „lexikografické“ pořadí.
Jinými slovy, řetězce se porovnávají písmeno po písmenu.
Například:
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true
Algoritmus pro porovnání dvou řetězců je jednoduchý:
- Porovnejte první znak obou řetězců.
- Pokud je první znak z prvního řetězce větší (nebo menší) než druhý řetězec, pak je první řetězec větší (nebo menší) než druhý. Máme hotovo.
- Jinak, pokud jsou první znaky obou řetězců stejné, porovnejte i druhé znaky stejným způsobem.
- Opakujte až do konce každého řetězce.
- Pokud oba řetězce končí na stejné délce, jsou si rovny. V opačném případě je delší řetězec větší.
V prvním příkladu výše je porovnání 'Z' > 'A'
se dostane k výsledku v prvním kroku.
Druhé srovnání 'Glow'
a 'Glee'
potřebuje více kroků, protože se řetězce porovnávají znak po znaku:
G
je stejný jakoG
.l
je stejný jakol
.o
je větší neže
. Zastavte tady. První řetězec je větší.
Výše uvedený srovnávací algoritmus je zhruba ekvivalentní tomu, který se používá ve slovnících nebo telefonních seznamech, ale není úplně stejný.
Například záleží na případu. Velké písmeno "A"
se nerovná malému "a"
. Který z nich je větší? Malé písmeno "a"
. Proč? Protože malé písmeno má větší index v interní kódovací tabulce používá JavaScript (Unicode). Ke konkrétním detailům a důsledkům toho se vrátíme v kapitole Řetězce.
Porovnání různých typů
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 2
alert( '01' == 1 ); // true, string '01' becomes a number 1
Pro booleovské hodnoty true
se změní na 1
a false
se změní na 0
.
Například:
alert( true == 1 ); // true
alert( false == 0 ); // true
Vtipný důsledek Je možné, že ve stejnou dobu:
- Dvě hodnoty se rovnají.
- Jedním z nich je
true
jako boolean a druhý jefalse
jako boolean.
Například:
let a = 0;
alert( Boolean(a) ); // false
let b = "0";
alert( Boolean(b) ); // true
alert(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 "0"
se změní na 0
), zatímco explicitní Boolean
konverze používá jinou sadu pravidel.
Přísná rovnost
Pravidelná kontrola rovnosti ==
má problém. Nelze rozlišit 0
od false
:
alert( 0 == false ); // true
Totéž se stane s prázdným řetězcem:
alert( '' == false ); // true
K tomu dochází, protože operandy různých typů jsou převedeny na čísla operátorem rovnosti ==
. Prázdný řetězec, stejně jako false
, se změní na nulu.
Co dělat, když chceme odlišit 0
od false
?
Operátor přísné rovnosti ===
kontroluje rovnost bez převodu typu.
Jinými slovy, pokud a
a b
jsou různých typů, pak a === b
okamžitě vrátí false
bez pokusu o jejich konverzi.
Zkusme to:
alert( 0 === false ); // false, because the types are different
Existuje také operátor „přísné nerovnosti“ !==
analogicky k !=
.
Operátor přísné rovnosti je o něco delší na psaní, ale dává jasně najevo, co se děje, a ponechává méně prostoru pro chyby.
Porovnání s hodnotami null a undefined
Když null
, dochází k neintuitivnímu chování nebo undefined
jsou porovnány s jinými hodnotami.
- 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. Tito dva jsou „sladký pár“:jsou si rovni (ve smyslu
==
), ale žádnou jinou hodnotu.alert( null == undefined ); // true
- Pro matematiku a další srovnání
< > <= >=
-
null/undefined
jsou převedeny na čísla:null
se změní na0
, zatímcoundefined
se změní naNaN
.
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 s nimi nepadnout do pasti.
Podivný výsledek:null vs 0
Porovnejme null
s nulou:
alert( null > 0 ); // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
Matematicky je to zvláštní. Poslední výsledek uvádí, že „null
je větší nebo rovno nule", takže v jednom z výše uvedených srovnání musí být true
, ale oba jsou nepravdivé.
Důvodem je kontrola rovnosti ==
a porovnání > < >= <=
pracovat jinak. Porovnání převádí null
na číslo, zacházet s ním jako 0
. Proto (3) null >= 0
je true a (1) null > 0
je nepravdivé.
Na druhou stranu kontrola rovnosti ==
pro undefined
a null
je definován tak, že bez jakýchkoli konverzí se navzájem rovnají a nerovnají se ničemu jinému. Proto (2) null == 0
je nepravdivé.
Nesrovnatelné nedefinované
Hodnota undefined
by neměly být porovnávány s jinými hodnotami:
alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
Proč nemá tak rád nulu? Vždy nepravda!
Tyto výsledky získáváme, protože:
- Srovnání
(1)
a(2)
návratfalse
protožeundefined
se převede naNaN
aNaN
je speciální číselná hodnota, která vracífalse
pro všechna srovnání. - Kontrola rovnosti
(3)
vrátífalse
protožeundefined
rovná se pouzenull
,undefined
a žádnou jinou hodnotu.
Vyhněte se problémům
Proč jsme procházeli těmito příklady? Měli bychom si tyto zvláštnosti neustále připomínat? No ne tak úplně. Ve skutečnosti se tyto záludné věci postupem času postupně stanou známými, ale existuje solidní způsob, jak se s nimi vyhnout problémům:
- Zachovejte jakékoli srovnání s
undefined/null
kromě přísné rovnosti===
s mimořádnou péčí. - Nepoužívejte srovnání
>= > < <=
s proměnnou, která může býtnull/undefined
pokud si nejste opravdu jisti tím, co děláte. Pokud proměnná může mít tyto hodnoty, zkontrolujte je samostatně.
Shrnutí
- Operátory porovnání vrací booleovskou hodnotu.
- Řetězce se porovnávají písmeno po písmenu v pořadí „slovníku“.
- Při porovnání hodnot různých typů se převedou na čísla (s vyloučením přísné kontroly rovnosti).
- Hodnoty
null
aundefined
rovno==
navzájem a nerovnají se žádné jiné hodnotě. - Buďte opatrní při používání srovnání jako
>
nebo<
s proměnnými, které občas mohou býtnull/undefined
. Kontrolanull/undefined
odděleně je dobrý nápad.