Srovnání

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 jeden a = b znamená úkol.
  • Nerovná se:V matematice je zápis , ale v JavaScriptu je zapsán jako a != 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ý:

  1. Porovnejte první znak obou řetězců.
  2. 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.
  3. Jinak, pokud jsou první znaky obou řetězců stejné, porovnejte i druhé znaky stejným způsobem.
  4. Opakujte až do konce každého řetězce.
  5. 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:

  1. G je stejný jako G .
  2. l je stejný jako l .
  3. o je větší než e . Zastavte tady. První řetězec je větší.
Ne skutečný slovník, ale řád Unicode

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ý je false 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í na 0 , zatímco undefined se změní na 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 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ávrat false protože undefined se převede na NaN a NaN je speciální číselná hodnota, která vrací false pro všechna srovnání.
  • Kontrola rovnosti (3) vrátí false protože undefined rovná se pouze null , 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ýt null/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 a undefined 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ýt null/undefined . Kontrola null/undefined odděleně je dobrý nápad.