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:
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:
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:
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:
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:
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:
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ý:
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
aundefined
– tieto hodnoty je vhodné porovnávať pomocou pretypovania.""
alebo'' (prázdny reťazec)
, číslo0
aNaN
– tieto hodnoty môžu mať vlastný význam v kóde, ako sme spomenuli vyššie. Niekedy má zmysel nastaviť premennú hodnotu0
, 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ú akofalse
, 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