IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

21. diel - Striktné operátory a pretypovanie v JavaScripte

V minulej lekcii, Dokončenie editora tabuliek v JavaScripte, sme sa do editora tabuliek naučili vkladať stĺpce a riadky a mazať ich.

V dnešnom tutoriále sa budeme venovať pretypovaniu v JavaScripte. Popíšeme si, ako sa menia hodnoty premenných pri prevode z jedného dátového typu na iný. To môže totiž spôsobiť časté problémy najmä pri porovnávaní dvoch hodnôt v podmienkach. Pretypovanie nám však zároveň umožňuje zápis niektorých podmienok skrátiť, čo si ukážeme na konkrétnych príkladoch.

Porovnávanie a pretypovanie v JavaScripte

Pretypovanie v JavaScripte je proces, kedy sa premenná jedného dátového typu automaticky zmení na iný dátový typ. Je dobré vedieť, ako sa pri tomto procese menia hodnoty týchto premenných, aby sme sa vyhli nečakaným výstupom najmä pri ich porovnaní v podmienkach.

Pretypovaniu je v JavaScripte pomerne komplikované téma, preto mu venujeme túto samostatnú lekciu. Nepokryjeme v nej všetky prípady, ale získame základný prehľad o tom, ako pretypovanie v JavaScripte funguje. Ukážeme si, ako sa vyhnúť možným problémom s pretypovaním a kde nám naopak pretypovanie pomôže písať prehľadnejší kód.

Striktné operátory

Na porovnávanie používame relačné operátory, ktoré sme si uviedli v lekcii Podmienky v JavaScripte. Vieme, že medzi nich patrí aj striktný operátor === a jeho negácia !==. Pri porovnávaní premenných vracia prvý striktný operátor true iba v prípade, keď sú obe premenné rovnakého dátového typu a majú zhodnú hodnôt. Operátor !== potom vráti true, keď porovnávame rozdielne hodnoty alebo rozdielne dátové typy.

Pre pripomenutie si ukážme príklad, ktorý demonštruje rozdiel medzi porovnávaním operátorom == a operátorom ===:

document.write('Equality by value (1 == "1"): ' + (1 == '1') + '<br>');
document.write('Equality by value and type (1 === "1"): ' + (1 === '1') + '<br>');

Ukážka aplikácie v prehliadači:

== vs. ===
localhost

Prvá podmienka sa vyhodnotí ako pravdivá, pretože sa porovnávajú len hodnoty. Presnejšie povedané, tu najskôr dôjde k pretypovaniu textu "1" (string) na číslo 1 (number) a následné porovnanie sa vyhodnotí ako true. U druhej podmienky kvôli striktnému operátorovi === k pretypovaniu nedochádza, číslo sa takto nemôže rovnať textu, preto sa podmienka vyhodnotí ako false.

Vo väčšine prípadov je tak dobrým zvykom ich používať striktné operátory === a !== a nedovoliť tak žiadne pretypovanie pri porovnávaní.

Ukážme si ešte výstup podmienok s operátorom !==:

document.write((5 !== '5') + '<br>'); // true: The number 5 is not equal to the text '5'.
document.write((10 !== 20) + '<br>'); // true: The value of the two numbers is different.
document.write((5 !== 'five') + '<br>'); // true: Neither value nor data type is equal.
document.write(('five' !== 'five') + '<br>'); // false: Both the value and the data type are equal.

V prehliadači sa nám vypíše:

!==
localhost

Vidíme, že tento operátor vracia vo väčšine prípadov true. Vráti false iba v prípade, keď porovnávame dve premenné rovnakej hodnoty a rovnakého typu.

Zvláštnosti pretypovania

Používanie operátorov == a != pri porovnávaní rôznych dátových typov môže mať niekedy nečakané výsledky, pretože pravidlá pre pretypovanie sú často mätúce. Pre ukážku sa teraz pozrime na pár typických výsledkov pretypovania, ktoré by sme asi nečakali:

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

Keby sme v uvedenej ukážke použili operátor ===, všetky podmienky by sa vyhodnotili ako false. Hoci sa môže zdať, že nestriktné operátory (== a !=) sú pohodlné vďaka automatickému pretypovaniu porovnávaných hodnôt, môžu byť zdrojom neočakávaných chýb v kóde.

Kompletný zoznam pretypovania rôznych hodnôt a dátových typov pri porovnávaní operátorom == nájdeme v tabuľke JavaScript Equality Table na GitHube.

Skrátenie podmienok pomocou pretypovania

Zatiaľ sme si ukázali iba problémy spojené s pretypovaním a možnosť, ako sa im vyhnúť pomocou striktných operátorov. Pokiaľ sme si však istí, že vieme, čo sa počas pretypovania s danou premennou stane, je dobré ho pri práci využiť. Pretypovanie je nástroj, ktorý nám môže pomôcť, ale zároveň spôsobiť problémy. Je teda dobré sa s ním naučiť pracovať správne.

V tejto časti sa pozrieme, ako využiť automatické pretypovanie vo svoj prospech, aby sme dosiahli efektívnejší a čistejší kód.

Overenie neprázdneho reťazca

Majme príklad, kedy nám používateľ zadá svoje meno a my chceme skontrolovať, či ho naozaj zadal. Budeme teda kontrolovať, či má zadané meno dĺžku väčšiu ako 0. Príklad by mohol vyzerať nasledovne:

let name = prompt('Fill in your name');
if (name.length > 0)
    document.write('The name was filled.');
else
    document.write('The name was not filled.');

Vďaka pretypovaniu môžeme podmienku skrátiť iba na:

let name = prompt('Fill in your name');
if (name.length)
    document.write('The name was filled.');
else
    document.write('The name was not filled.');

Vlastnosť length je typu number, ktorý sa pri hodnote 0 vyhodnotí ako false a pri akejkoľvek inej ako true.

Tú istú podmienku môžeme dokonca zapísať aj len takto:

let name = prompt('Fill in your name');
if (name)
    document.write('The name was filled.');
else
    document.write('The name was not filled.');

Pokiaľ by meno nebolo vyplnené a namiesto neho bol uložený prázdny reťazec '', dôjde k pretypovaniu na false. V opačnom prípade na true.

Overenie neprázdneho poľa

Podobným postupom môžeme overiť, či máme prázdne pole alebo či pole niečo obsahuje:

let numbers = [1, 2, 3];
if (numbers.length)
    document.write('The array of numbers is not empty.');
else
    document.write('The array of numbers is empty.');

Celý kód bude fungovať rovnako, ako keby sme v podmienke napísali (cisla.length > 0).

Tu však pozor! Ako sme videli, prázdny reťazec sa vyhodnotí ako false. Pri poli je to rozdielne, prázdne pole sa vyhodnotí ako true. Preto sa pri poli musíme pýtať na jeho dĺžku length.

Vyskúšajme si ešte skrátený zápis podmienky na prázdnom poli:

let receivedNumbers = [];
if (receivedNumbers.length) // 'if (receivedNumbers)' would always return true!
    document.write('The array of received numbers is not empty.');
else
    document.write('The array is empty for now.');

Výstup uvedených príkladov v prehliadači bude nasledujúci:

Non-empty and empty array validation
localhost

Podmienky s null

Praktický príklad použitia null v podmienke nám umožní metóda getElementById().

S metódou getElementById() sme sa zoznámili v lekcii Základy práce s DOM a udalosti v JavaScripte.

Táto metóda vracia v prípade úspechu prvý nájdený element, a to ako dátový typ object. V prípade neúspechu vracia null, čím spoznáme, že sa daný element na stránke nenachádza.

Ukážme si príklad:

let htmlElement = document.getElementById('result');
if (htmlElement !== null) {
    // found
    document.write('element found');
} else {
    // not found
    document.write('element not found');
}

Keďže sa null pretypuje na false a object na true, môžeme podmienku zapísať aj skrátene:

let htmlElement = document.getElementById('result');
if (htmlElement) {
    // found
    document.write('element found');
} else {
    // not found
    document.write('element not found');
}

Výsledok:

Your page
localhost

Skrátený zápis podmienky je obľúbený medzi mnohými vývojármi, pretože je stručnejší a vie ho správne použiť aj prečítať v cudzom kóde. V kontextoch, kde ide jasne rozlíšiť medzi pravdivou a nepravdivou hodnotou, je skrátený zápis účinný a elegantný.

Podmienky s undefined

Iste si pamätáme, že dátový typ undefined má premenná, pokiaľ ju deklarujeme a nepriradíme zatiaľ žiadnu hodnotu:

let age;
document.write(typeof age);

Výpis v prehliadači:

Your page
localhost

Starší zápis východiskovej hodnoty parametra funkcie

Ako praktický príklad si ukážeme použitie hodnoty undefined, na ktoré narazíme v starších kódoch pri nastavovaní východiskovej hodnoty parametra funkcie. Predtým sa tento problém riešil nasledujúcim zápisom:

function greet(language) {
    if (language === undefined)
        language = 'en'; // default value

    if (language === 'en')
        document.write('Hello World!');
    else if (language === 'sk')
        document.write('Ahoj svete!');

    document.write('<br>');
}

greet();
greet('sk');

Výsledok:

Your page
localhost

Funkcia si najskôr otestuje, či je parameter language zadaný. Pokiaľ nie je, priradí mu predvolenú hodnotu 'en'.

Pretože sa undefined pretypuje na false, tak by nás možno napadlo vo funkcii napísať podmienku v tvare:

if (!language)
    language = 'en';

To by v našom prípade fungovalo, ale nie je to dobrý nápad. Tu je treba myslieť na to, že ak odovzdávame string, tak prázdny string sa opäť vyhodnotí ako false. Rovnako keby sme v parametri odovzdávali číslo a zadali hodnotu 0, vyhodnotila by sa ako false. Zatiaľ čo prázdny jazyk nedáva v prípade parametra veľký zmysel, prázdny oddeľovač hodnôt ('', bez medzery) alebo číslo 0 by už mohol byť úmysel.

Nový zápis východiskovej hodnoty parametra

Vráťme sa ešte k predchádzajúcemu príkladu. Vďaka štandardu ES6 (ECMAScript 6) z roku 2015 je možné východiskovú hodnotu parametra funkcie zapísať lepšie. Predvolenú hodnotu môžeme jednoducho priradiť priamo k parametru pri deklarácii funkcie. Nemusíme tak potom kontrolovať, či bol parameter zadaný:

function greet(language= 'en') {
    if (language === 'en')
        document.write('Hello World!');
    else if (language=== 'sk')
        document.write('Ahoj svete!');

    document.write('<br>');
}

greet();
greet('sk');

Výsledok bude rovnaký:

Your page
localhost

Zhrnutie

V JavaScripte existuje niekoľko hodnôt, ktoré sa vyhodnotia ako false. Pretože môžu mať rôzne významy a použitie v kóde, rozdelíme si ich do dvoch skupín:

  • false, null a undefined – tieto hodnoty je vhodné porovnávať pomocou pretypovania.
  • "" alebo '' (prázdny reťazec), číslo 0 a NaN – tieto hodnoty môžu mať vlastný význam v kóde, ako sme spomenuli vyššie. Niekedy má zmysel nastaviť premennú hodnotu 0, zadať ako parameter prázdny reťazec alebo uložiť informáciu o tom, že sme získali nečíselný výsledok. Ale pozor, v podmienke sa tieto tri hodnoty spracujú ako false, preto je vo väčšine prípadov lepšie porovnávať ich pomocou striktných operátorov.

Ukážme si prehľad najčastejšie používaných hodnôt, doplnený ďalšími hodnotami, v tabuľke:

Zadaná hodnota v podmienke 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 tu aj príklady, ktoré sme si už vyskúšali. Napríklad prázdne pole [], ktoré je v podmienke vyhodnotené ako true. Túto tému pretypovania už kompletne opustíme.

V ďalšej lekcii, Podmienky v JavaScripte tretíkrát, sa vrátime k podmienkam a ukážeme si ďalšie konštrukcie na tvorbu podmienok.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 2x (1.31 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Dokončenie editora tabuliek v JavaScripte
Všetky články v sekcii
Základné konštrukcie jazyka JavaScript
Preskočiť článok
(neodporúčame)
Podmienky v JavaScripte tretíkrát
Článok pre vás napísal Roman
Avatar
Užívateľské hodnotenie:
5 hlasov
Roman
Aktivity