IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 20 - 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í veškeré případy, 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 naopak přetypování pomůže 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 hodnot. 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:

== vs. ===
localhost

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 tak dobrým zvykem je 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:

!==
localhost

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.

Vyzkoušejme si ještě zkrácený zápis podmínky na prázdném poli:

let ziskanaCisla = [];
if (ziskanaCisla.length) // 'if (ziskanaCisla)' by zde vrátilo vždy true!
    document.write('Pole získaných čísel není prázdné.');
else
    document.write('Zatím máme pole prázdné.');

Výstup uvedených příkladů v prohlížeči bude následující:

Ověření neprázdného a prázdného pole
localhost

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) {
    // nalezeno
    document.write('Element nalezen');
} else {
    // nenalezeno
    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) {
    // nalezeno
    document.write('Element nalezen');
} else {
    // nenalezeno
    document.write('Element nenalezen');
}

Výsledek:

Tvoje stránka
localhost

Zkrácený zápis podmínky je oblíbený mezi mnoha vývojáři, protože je stručnější a umí ho správně použít i přečíst v cizím kódu. V kontextech, kde jde jasně rozlišit mezi pravdivou a nepravdivou hodnotou, je zkrácený zápis účinný 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:

Tvoje stránka
localhost

Starší zápis výchozí hodnoty parametru funkce

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 následujícím zápisem:

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:

Tvoje stránka
localhost

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 myslet na to, že pokud předáváme string, tak prázdný string se opět vyhodnotí jako false. Stejně tak kdybychom v parametru předávali číslo a zadali hodnotu 0, vyhodnotila by se jako false. Zatímco prázdný jazyk nedává v případě parametru valný smysl, prázdný oddělovač hodnot ('', bez mezery) nebo číslo 0 by již mohl být úmysl.

Nový zápis výchozí hodnoty parametru

Vraťme se ještě k předchozímu příkladu. 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ý:

Tvoje stránka
localhost

Shrnutí

V JavaScriptu existuje několik hodnot, které se vyhodnotí jako false. Protože mohou mít různé významy a použití v kódu, rozdělíme si je do dvou skupin:

  • false, null a undefined – tyto hodnoty je vhodné porovnávat pomocí přetypování.
  • "" nebo '' (prázdný řetězec), číslo 0 a NaN – tyto hodnoty mohou mít vlastní význam v kódu, jak jsme zmínili výše. Někdy má smysl nastavit proměnné hodnotu 0, 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í jako false, 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, doplněný dalšími hodnotami, 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 41x (1.32 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Dokončení editoru tabulek v JavaScriptu
Všechny články v sekci
Základní konstrukce jazyka JavaScript
Přeskočit článek
(nedoporučujeme)
Podmínky v JavaScriptu potřetí
Článek pro vás napsal Roman
Avatar
Uživatelské hodnocení:
714 hlasů
Roman
Aktivity