ITnetwork summer 2020
Pouze tento týden sleva až 80 % na e-learning týkající se Pythonu
80 % bodů zdarma na online výuku díky naší Letní akci!

Lekce 12 - 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 před, za, nad, pod a taky je mazat.

V předešlé lekci o podmínkách, Podmínky v JavaScriptu jsme si slíbili, že se k nim v kurzu ještě jednou vrátíme. V dnešní lekci si proto ukážeme časté problémy s používáním podmínek.

Striktní operátory podruhé

Již jsme se setkali s operátory ==, ===, !=, !== a porovnáváním různých datových typů. Pro připomenutí si ukážeme příklad, který demonstruje rozdíl mezi porovnáváním hodnotou operátorem == a porovnáváním hodnotou a typem operátorem ===:

if (1 == '1')
    document.write('Rovnost hodnotou.');
if (1 === '1')
    document.write('Rovnost hodnotou a typem.');

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 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í, proto se vyhodnotí jako false, protože číslo se takto nemůže rovnat textu.

Přetypování je v JavaScriptu poměrně komplikované téma a vydalo by na celý samostatný kurz. My mu věnujeme tuto samostatnou lekci. Ukážeme si, jak se vyhnout častý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.

Volba operátoru

Jaký operátor pro porovnání tedy používat? Dobrým zvykem je používat striktní operátory === a !== a nedovolit tak žádnému přetypování při porovnávání.

Používání operátorů == a != při porovnávání různých datových typů může mít totiž nečekané výsledky, protože pravidla pro přetypování jsou mnohdy matoucí. Vzpomínáte si na úvodní lekci, kde jsme si řekli, že JavaScript byl navržený za 14 dní? Pro ukázku se 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

Zkuste se zamyslet, proč byly podmínky takto vyhodnoceny. Nejste si jisti nebo nevíte? Nevadí, stačí požívat striktní operátor ===, který se bude chovat podle očekávání. Předchozí ukázka s operátorem === by se vždy vyhodnotila jako false.

Kompletní tabulku s přetypováním různých hodnot a datových typů při porovnávání operátorem == naleznete na: https://dorey.github.io/…ality-Table/

Zkrácení podmínek pomocí přetypování

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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ů. Teď si ukážeme několik příkladů, kde naopak přetypování využijeme ve svůj prospěch.

Ověření neprázdného řetězce

Mějme následující příklad: Uživatel nám zadá své jméno a my chceme zkontrolovat, zda ho opravdu zadal. Budeme tedy kontrolovat, zda má zadané jméno větší délku 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. Tyto zkrácené zápisy budeme ve svých skriptech preferovat.

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 pole = [1, 2, 3];
if (pole.length)
    document.write('Pole není prázdné.');
else
    document.write('Pole je prázdné.');

Zde pozor! Na rozdíl od řetězce, který se prázdný vyhodnotí jako false, se prázdné pole vyhodnotí jako true! Proto se u pole musíme ptát na jeho délku length. Výsledek v prohlížeči:

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

Podmínky s null

Praktický příklad použití null v podmínce nám umožní metoda getElementById(). Tato metoda vrací v případě úspěchu hledaný 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í:

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

Výsledek:

Your page
localhost

Podmínky s undefined

Jistě si pamatujete, že datový typ undefined má proměnná, pokud ji deklarujeme a nepřiřadíme zatím žádnou hodnotu:

let promena;
document.write(typeof promena);

Výsledek:

Your page
localhost

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

Praktický příklad může být použití funkce s nebo bez parametru, na který narazíte ve starších kódech. Tam se můžete setkat s následujícím zápisem:

function pozdrav(jazyk) {
    // výchozí hodnota
    if (jazyk === undefined)
        jazyk = 'en';

    if (jazyk === 'en')
        document.write('Hello World!');
    else if (jazyk === 'cz')
        document.write('Ahoj světe!');
    //...
}

pozdrav();
pozdrav('cz');

Výsledek:

Your page
localhost

Funkce si nejprve otestuje, zda je zadaný parametr a pokud není, přiřadí mu výchozí hodnotu 'en'.

Protože se undefined přetypuje na false, tak by vá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ý případ by mohl nastat v případě s číslem, kde by se předala 0. Zatímco prázdný jazyk nedává v případě parametru valný smysl, prázdný oddělovač hodnot nebo číslo 0 by již mohl být úmysl.

ES6 zápis výchozí hodnoty parametru

Vraťme se ještě k předchozímu příkladu. Díky ES6 jej lze zapsat ještě lépe, výchozí hodnotu můžeme přiřadit přímo k parametru a nemusíme tak ve funkci 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!');
    //...
}

pozdrav();
pozdrav('cz');

Výsledek:

Your page
localhost

To je k dnešní lekci o přetypování vše.

V další lekci, Podmínky v JavaScriptu podruhé, si prohloubíme naše znalosti o datových typech a ukážeme si další konstrukce pro tvorbu podmínek.


 

Předchozí článek
Dokončení editoru tabulek v JavaScriptu
Všechny články v sekci
Základní konstrukce jazyka JavaScript
Článek pro vás napsal Roman
Avatar
Jak se ti líbí článek?
3 hlasů
Aktivity (7)

 

 

Komentáře

Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:9. března 10:24

Přiznám se, že jsem byl v šoku, když jsem četl ten nadpis - JavaScript a přetypování.
Ale koukám, že tady se to bere trošku jinak, než v Javě. Z mého pohledu je to pouze jiná forma zápisu podmínky, ale to asi jen proto, protože jsem odkojený Javou a přetypování pro mě znamená něco jiného.
Logiku to má, své kouzlo také, ale pro mě, jako Javistu je to další důvod, proč nemít rád JavaScript:)

Odpovědět
9. března 10:24
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Taskkill
Redaktor
Avatar
Odpovídá na Lubor Pešek
Taskkill:10. března 11:17

Na podmínkách to ale není závislé. Jde prostě o operátory porovnání produkující pravdivostní hodnoty.
Nestriktní verze porovnání provádí typový převod, který sice nefunguje jako explicitní cast v Javě, ale pořád je to přetypování na jiný type.
JavaScript má typesystem dost odlišný od Javy, stejně jako se ten v Javě liší od toho v C++, kde se například ještě dá definovat operátor bool a získat tak ještě větší kontrolu nad podmínkami.
Ultimátně ale jde o typy a i když jsou v JS typy dynamické, pořád jsou to typy a dovolují v závislosti na nějakých pravidlech převody (i když implicitní).

 
Odpovědět
10. března 11:17
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Taskkill
Lubor Pešek:10. března 12:03

No však já to beru (kdyby to bylo všechno 1:1, nebylo by potřeba víc jazyků).
Proto jsem také psal tu poslední větu, že je to hlavně problém ve mě, protože jsem odkojený Javista.
No a jak by řekl klasik - můžu s tím nesouhlasit, můžu protestovat, ale to je asi tak všechno, co s tím můžu dělat:)

Já prostě nejsem přítelem, aby se úplně všechno zkracovalo, protože to tak jde.
Je sice fajn, že takhle redukuju kód, ale potom to vyvíjej.

Odpovědět
10. března 12:03
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Odpovídá na Lubor Pešek
Vladislav Ladicky:11. března 13:19

Nemať rád JS lebo je dynamicky typovaný vlastne znamená nemať rád všetky dynamicky typované jazyky, čiže napríklad aj Python. A také prehlásenia od kohokoľvek kto sa pokladá za programátora mi pripadajú ... divné? Či nedostatok vzdelania v oblasti? Je to ako tvrdiť, že Audi A8 W12 Long s automatom je nekvalitné auto, ale to isté Audi s manuálom už je kvalitné auto. Čo ja viem...

 
Odpovědět
11. března 13:19
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Vladislav Ladicky
Lubor Pešek:11. března 13:35

13 let jsem programoval pouze a jenom v Javě...
To je to samé, jako když někdo programuje celý život strukturovaně, vyvine řadu funkčních projektů a najednou má začít programovat objektově.

Já neříkám, že je to špatné, že je to něco nekvalitiního nebo na to nenadávám.
Myslím si, že základem dobrého programátora je i umět pořádně číst a pochopit myšlenku a pokud nedovedeš pochopit větu:

Proto jsem také psal tu poslední větu, že je to hlavně problém ve mě, protože jsem odkojený Javista

tak mi to přijde ještě divnější.

Tohle nebyl komentář, který by byl nějakým přínosem. Prostě jsem jen napsal svůj subjektivní pocit (okomentoval jsem to ze svého pohledu). Na to mám snad ještě doufám právo. Prostě jsem popsal svůj pohled na to, jaké to je, když někdo dlouho dělá v jednom jazyce a přechází do jiného.

Odpovědět
11. března 13:35
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Odpovídá na Lubor Pešek
Vladislav Ladicky:11. března 14:51

Ako veď ok - prezentoval si svoj subjektívny názor na JS, ja som prezentoval svoj subjektívny názor na programátora so subjektívnym názorom na JS. A na to snáď mám tiež právo. Či?

Mrzí ma to. Ja len nemám rád podobné "subjektívne názory", lebo nepatria do tejto oblasti, ktorá má byť založená na objektívnej logike, nie na subjektívnych názoroch. Ak to založíme na subjektivite, nevysomárime sa nikdy z toho čo je pravda a čo nie. Lebo napríklad Ti sem viem dať link na článok od ďaleko ťažšieho kalibru na Javu, Java programátora priamo od Sunu, ktorý bol nútený použiť JS a odkedy sa ho naučil, je z neho nadšený. Aj z jeho syntaxu, aj z toho, že je dynamicky typovaný. A kde je potom pravda? Keď už, skôr uverím tomu ťažkému profesionálovi, ako tebe. Či?

 
Odpovědět
11. března 14:51
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Vladislav Ladicky
Lubor Pešek:11. března 15:02

No vidíš a nám se ve firmě už mnohokrát stalo, že jsme museli javascriptové kódy přepisovat do Javy (převážně kvůli stabilitě).

Přiznám se, že doteď netuším, o co ti jde... Chceš konflikt? to si na to najdi někoho jiného.Sám sem teď nucený se tento jazyk učit (důvody si raději ponechám, protože koukám, že psycholog tvého ražení by mě v podstatě zkritizoval na konci i pro můj celký způsob života, takže ponechme to na úrovni, že mám k tomu pro mě závažné důvody).
Učím se to a porovnávám s rize objektovým jazykem. Ten má svá pravidla, která fungují.Porovnávám to s jazykem, který OOP pochopil tak, že prostě všechno je objekt (včetně funkcí i atributů objektu).

Vidím v tom celkově dvě podstatné výhody oproti Javy, ale řadu nevýhod.
Však počkej sám, až se za pár let budeš učit úplně nový jazyk, který bude založen na jiném principu, než je OOP. Snad se nenajde takový psycholog, jako teď ty, který ti bude kritizovat tvůj názor a okamžitě spekulovat o tom, jaký jsi vlastně programátor;)

Odpovědět
11. března 15:02
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Taskkill
Redaktor
Avatar
Odpovídá na Lubor Pešek
Taskkill:11. března 22:32

Já jsem vůbec nechtěl implikovat, že je v tobě nějaký problém, nebo ve tvém pohledu.

Jen mě napadlo, že bych ti zkusil nabídnout svůj pohled/znalost tématu.

Ne že bych měl k tomu snad nějaký důvod ;-) ale myslím, že by se hodilo říct, že nepovažuju za divný jakýkoliv tvůj názor na dynamicky typované jazyky. I kdybys je skutečně odsuzoval - což tak nevypadá - je to jenom tvoje věc a není nutný, aby měl kdokoliv objektivní nebo na logice založený názory na programovací jazyky. To by bylo kontraproduktivní. Ne všechny jazyky skutečně stojí na tak pevných logických základech jak tu zaznělo :-D to rozhodně ne a naprostá většina z nich si nese opravdu velkou řádku čistě subjektivních rozhodnutí a myšlenek ať už kolem syntaxe nebo typesystemu nebo jinde.

Držím ti palce s tvým questem, kdo ví možná si jednou JS třeba i oblibíš.

 
Odpovědět
11. března 22:32
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.