Lekce 22 - Striktní operátory a přetypování v JavaScriptu
V minulé lekci, Dokončení editoru tabulek v JavaScriptu, jsme se do editoru tabulek naučili vkládat sloupce a řádky a mazat je.
V dnešním tutoriálu se budeme věnovat přetypování v JavaScriptu. Popíšeme si, jak se mění hodnoty proměnných při převodu z jednoho datového typu na jiný. To může totiž způsobit časté problémy zejména při porovnávání dvou hodnot v podmínkách. Přetypování nám však zároveň umožňuje zápis některých podmínek zkrátit, což si ukážeme na konkrétních příkladech.
Porovnávání a přetypování v JavaScriptu
Přetypování v JavaScriptu je proces, kdy se proměnná jednoho datového typu automaticky změní na jiný datový typ. Je dobré vědět, jak se při tomto procesu mění hodnoty těchto proměnných, abychom se vyhnuli nečekaným výstupům, zejména při jejich porovnání v podmínkách.
Přetypování je v JavaScriptu poměrně komplikované téma, proto mu věnujeme tuto samostatnou lekci. Nepokryjeme v ní všechny případy, které mohou nastat, ale získáme základní přehled o tom, jak přetypování v JavaScriptu funguje. Ukážeme si, jak se vyhnout možným problémům s přetypováním a kde nám přetypování naopak může pomoci psát přehlednější kód.
Striktní operátory
K porovnávání používáme relační operátory, které
jsme si uvedli v lekci Podmínky
v JavaScriptu. Víme, že mezi ně patří i striktní
operátor ===
a jeho negace !==
. Při
porovnávání proměnných vrací první striktní operátor true
pouze v případě, když jsou obě proměnné stejného datového
typu a mají shodnou hodnotu. Operátor
!==
pak vrátí true
, když porovnáváme rozdílné
hodnoty nebo rozdílné datové typy.
Pro připomenutí si ukažme příklad, který demonstruje rozdíl mezi
porovnáváním operátorem ==
a operátorem ===
:
document.write('Rovnost hodnotou (1 == "1"): ' + (1 == '1') + '<br>'); document.write('Rovnost hodnotou a typem (1 === "1"): ' + (1 === '1') + '<br>');
Ukázka aplikace v prohlížeči:
První podmínka se vyhodnotí jako pravdivá, protože se porovnávají jen
hodnoty. Přesněji řečeno zde nejprve dojde k přetypování
textu "1"
(string
) na číslo 1
(number
) a následné porovnání se vyhodnotí jako
true
. U druhé podmínky kvůli striktnímu operátoru
===
k přetypování nedochází. Číslo se takto
nemůže rovnat textu, proto se podmínka vyhodnotí jako
false
.
Ve většině případů je dobrým zvykem používat striktní
operátory ===
a !==
a nedovolit tak žádné
přetypování při porovnávání.
Ukažme si ještě výstup podmínek s operátorem !==
:
document.write((5 !== '5') + '<br>'); // true: Číslo 5 není rovno textu '5'. document.write((10 !== 20) + '<br>'); // true: Hodnota dvou čísel je jiná. document.write((5 !== 'five') + '<br>'); // true: Není rovna ani hodnota ani datový typ. document.write(('five' !== 'five') + '<br>'); // false: Je rovna hodnota i datový typ.
V prohlížeči se nám vypíše:
Vidíme, že tento operátor vrací ve většině případů
true
. Vrátí false
pouze v případě, kdy
porovnáváme dvě proměnné stejné hodnoty a stejného typu.
Zvláštnosti přetypování
Používání operátorů ==
a !=
při
porovnávání různých datových typů může mít někdy nečekané
výsledky, protože pravidla pro přetypování jsou mnohdy matoucí. Pro
ukázku se nyní podívejme na pár typických výsledků přetypování, které
bychom asi nečekali:
if ('' == '0') // false if ('' == 0) // true if (0 == '0') // true if (false == 'false') // false if (false == '0') // true if (false == undefined) // false if (false == null) // false if (null == undefined) // true
Kdybychom v uvedené ukázce použili operátor ===
, všechny
podmínky by se vyhodnotily jako false
. Ačkoli se může zdát,
že nestriktní operátory (==
a !=
) jsou pohodlné
díky automatickému přetypování porovnávaných hodnot,
mohou být zdrojem neočekávaných chyb v kódu.
Kompletní výčet přetypování různých hodnot a datových
typů při porovnávání operátorem ==
nalezneme v tabulce JavaScript
Equality Table na GitHubu.
Zkrácení podmínek pomocí přetypování
Zatím jsme si ukázali jen problémy spojené s přetypováním a možnost, jak se jim vyhnout pomocí striktních operátorů. Pokud jsme si však jisti, že víme, co se během přetypování s danou proměnnou stane, je dobré jej při práci využít. Přetypování je nástroj, který nám může pomoci, ale zároveň způsobit problémy. Je tedy dobré se s ním naučit pracovat správně.
V této části se podíváme, jak využít automatické přetypování ve svůj prospěch, abychom dosáhli efektivnějšího a čistšího kódu.
Ověření neprázdného řetězce
Mějme příklad, kdy nám uživatel zadá své jméno a my chceme
zkontrolovat, zda ho opravdu zadal. Budeme tedy kontrolovat, zda má zadané
jméno délku větší než 0
. Příklad by mohl vypadat
následovně:
let jmeno = prompt('Vyplňte vaše jméno'); if (jmeno.length > 0) document.write('Jméno vyplněno.'); else document.write('Jméno nebylo vyplněno.');
Díky přetypování můžeme podmínku zkrátit pouze na:
let jmeno = prompt('Vyplňte vaše jméno'); if (jmeno.length) document.write('Jméno vyplněno.'); else document.write('Jméno nebylo vyplněno.');
Vlastnost length
je typu number
, který se při
hodnotě 0
vyhodnotí jako false
a při jakékoli
jiné jako true
.
Tu samou podmínku můžeme dokonce zapsat i jen takto:
let jmeno = prompt('Vyplňte vaše jméno'); if (jmeno) document.write('Jméno vyplněno.'); else document.write('Jméno nebylo vyplněno.');
Pokud by jméno nebylo vyplněno a místo něj byl uložený prázdný
řetězec ''
, dojde k přetypování na false
. V
opačném případě na true
.
Ověření neprázdného pole
Podobným postupem můžeme ověřit, zda máme prázdné pole nebo zda pole něco obsahuje:
let cisla = [1, 2, 3]; if (cisla.length) document.write('Pole čísel není prázdné.'); else document.write('Pole čísel je prázdné.');
Celý kód bude fungovat stejně, jako kdybychom v podmínce napsali
(cisla.length > 0)
:
Zde však pozor! Jak jsme viděli, prázdný řetězec se
vyhodnotí jako false
. U pole je to rozdílné, prázdné pole se
vyhodnotí jako true
. Proto se u pole musíme ptát na jeho
délku length
.
V příkladu, kde je pole prázdné, se podmínka vyhodnotí jako nepravdivá:
let cisla = []; if (cisla.length) document.write('Pole čísel není prázdné.'); else document.write('Pole čísel je prázdné.');
Výsledek:
Podmínky s null
Praktický příklad použití null
v podmínce nám umožní
metoda getElementById()
.
S metodou getElementById()
jsme se seznámili v
lekci Základy
práce s DOM a události v JavaScriptu.
Tato metoda vrací v případě úspěchu první nalezený element, a to jako
datový typ object
. V případě neúspěchu vrací
null
, čímž poznáme, že se daný element na stránce
nenachází.
Ukažme si příklad:
let htmlElement = document.getElementById('vysledek'); if (htmlElement !== null) { document.write('Element nalezen'); } else { document.write('Element nenalezen'); }
Jelikož se null
přetypuje na false
a
object
na true
, můžeme podmínku zapsat i
zkráceně:
let htmlElement = document.getElementById('vysledek'); if (htmlElement) { document.write('Element nalezen'); } else { document.write('Element nenalezen'); }
V případě, že se na naší stránce nalézá element se zadaným ID,
například <span id="vysledek"></span>
, podmínka se
vyhodnotí jako pravdivá:
Zkrácený zápis podmínek je mezi mnoha vývojáři oblíbený zejména pro svou stručnost. Je tedy důležité mu porozumět i proto, abychom lépe chápali cizí kód. V situacích, kde lze jednoznačně rozlišit mezi pravdivou a nepravdivou hodnotou, je tento zápis efektivní a elegantní.
Podmínky s undefined
Jistě si pamatujeme, že datový typ undefined
má proměnná,
pokud ji deklarujeme a nepřiřadíme zatím
žádnou hodnotu:
let vek; document.write(typeof vek);
Výpis v prohlížeči:
Nastavení
výchozí hodnoty parametru funkce pomocí undefined
Jako praktický příklad si ukážeme použití hodnoty
undefined
, na které narazíme ve starších
kódech při nastavování výchozí hodnoty parametru
funkce. Dříve se tento problém řešil takto:
function pozdrav(jazyk) { if (jazyk === undefined) jazyk = 'en'; // výchozí hodnota if (jazyk === 'en') document.write('Hello World!'); else if (jazyk === 'cz') document.write('Ahoj světe!'); document.write('<br>'); } pozdrav(); pozdrav('cz');
Výsledek:
Funkce si nejprve otestuje, zda je parametr jazyk
zadaný. Pokud
není, přiřadí mu výchozí hodnotu 'en'
.
Protože se undefined
přetypuje na false
, tak by
nás možná napadlo ve funkci napsat podmínku ve tvaru:
if (!jazyk) jazyk = 'en';
To by v našem případě fungovalo, ale není to dobrý nápad. Zde je
třeba mít na paměti, že pokud předáváme textový řetězec, prázdný
string
se opět vyhodnotí jako false
. Podobně, pokud
bychom předali číslo a nastavili hodnotu 0
, i ta by byla
vyhodnocena jako false
. Zatímco prázdný řetězec nemusí v
kontextu parametru pro jazykové nastavení dávat příliš smysl, prázdný
oddělovač hodnot (''
, bez mezery) nebo číslo 0
již mohou být v jiných situacích zadány úmyslně.
Nový zápis výchozí hodnoty parametru funkce
Díky standardu ES6 (ECMAScript 6) z roku 2015 lze výchozí hodnotu parametru funkce zapsat lépe. Výchozí hodnotu můžeme jednoduše přiřadit přímo k parametru při deklaraci funkce. Nemusíme tak poté kontrolovat, zda byl parametr zadán:
function pozdrav(jazyk = 'en') { if (jazyk === 'en') document.write('Hello World!'); else if (jazyk === 'cz') document.write('Ahoj světe!'); document.write('<br>'); } pozdrav(); pozdrav('cz');
Výsledek bude stejný:
Shrnutí
V JavaScriptu existuje několik hodnot, které se při přetypování
vyhodnotí jako false
. Vzhledem k tomu, že mohou mít v kódu
různé významy a použití, rozdělíme je do dvou skupin:
false
,null
aundefined
– tyto hodnoty je vhodné porovnávat pomocí přetypování.""
nebo''
(prázdný řetězec), číslo0
aNaN
– tyto hodnoty mohou mít vlastní význam v kódu, jak jsme zmínili výše. Někdy má smysl nastavit proměnné hodnotu0
, zadat jako parametr prázdný řetězec nebo uložit informaci o tom, že jsme získali nečíselný výsledek. Ale pozor, v podmínce se tyto tři hodnoty zpracují jakofalse
, proto je ve většině případů lepší porovnávat je pomocí striktních operátorů.
Ukažme si přehled nejčastěji používaných hodnot a jejich vyhodnocení při přetypování v tabulce:
Zadaná hodnota v podmínce | Výsledná hodnota |
---|---|
Infinity | true |
1 | true |
0 | false |
-1 | true |
-Infinity | true |
'1' | true |
'0' | true |
'-1' | true |
'true' | true |
'false' | true |
'' | false |
null | false |
undefined | false |
NaN | false |
[] | true |
{} (objekt) | true |
[[]] | true |
[0] | true |
[1] | true |
Vidíme zde i příklady, které jsme si již vyzkoušeli. Například
prázdné pole []
, které je v podmínce vyhodnoceno jako
true
. Tímto téma přetypování již kompletně opustíme.
V další lekci, Podmínky v JavaScriptu potřetí, se vrátíme k podmínkám a ukážeme si další konstrukce pro tvorbu podmínek.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 176x (1.32 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript