Základy programování v JavaScriptu

autor: Lukáš Michna


Aktualizováno 30. 5. 2019


Co je to programování

Programování v naprosto obecném významu znamená sestavování sady instrukcí, které mají být počítačem vykonány. V širším pojetí programování znamená rovněž analýzu problému a návrh jeho řešení (algoritmizace), přičemž toto řešení je popsáno právě v sadě instrukcí, které programátor ukládá počítači provést.

V jistém smyslu lze programování připodobnit ke tvorbě receptu nebo návodu. I ty se sestávají z popisu jednotlivých kroků, které je třeba vykonat, aby bylo dosaženo určitého výsledku. Zatímco v případě receptu či návodu je tím, kdo vykonává jednotlivé kroky, kuchař nebo osoba řídící se návodem, v případě počítačového programu to je počítač.

Procesem, ne nepodobným programování, může být i tvorba smlouvy, neboť i ta, je-li k její přípravě přistupováno s dostatečným rozmyslem, by měla vycházet z analýzy jejího předmětu a výsledkem by měl být dostatečně jasný popis výsledku zamýšleného stranami, včetně dostatečně návodného popisu postupu, jakým má být zamýšleného výsledku dosaženo.

Obdobně, proces aplikace práva lze zase připodobnit k postupu počítače, který postupuje podle zadaných instrukcí. V tomto bodě lze nicméně vypozorovat i jeden podstatný rozdíl mezi programováním (a prováděním programových instrukcí) a procesem tvorby a následné aplikace práva. Zatímco počítač provede jakoukoli instrukci zadanou programátorem, i tehdy, jedná-li se o instrukci vadnou (instrukce sama o sobě nicméně vadná být nemůže, vadný může být toliko výsledek jejího provedení s ohledem na rozpor se záměry či předpoklady programátora ohledně zamýšleného výsledku), v případě aplikace práva lze pomocí sofistikovaných metod výkladu (např. výklad teleologický) dosáhnout správné aplikace práva i v případech, kdy by mechanické provádění instrukcí vedlo k vadnému výsledku.

Uvažujeme-li o tom, že začmeme programovat, položíme si logickou otázku, jak a v čem tak budeme činit. Programovat, tedy sestavovat sadu instrukcí, je pochopitelně nutné v jazyce, kterému počítač rozumí.

Dle mého názoru jedním z programovacích jazyků, vhodných (nejen) k naučení se základů programování, je JavaScript. JavaScript je lehký, interpretovaný programovací jazyk, původně určený pro vytváření především interaktivních částí internetových stránek. JavaScript je tak velmi snadné používat, protože je integrován do každého internetového prohlížeče. Postupem času, společně s rozvojem webových technologií, se JavasScript vyvinul v programovací jazyk, kterým lze tvořit plnohodnotné aplikace. Jeho použití tak není omezeno pouze na učení se programování, ale může být i prostředkem ke tvorbě aplikací zamýšlených k produkčnímu nasazení.

Velkou výhodou JavaScriptu je, jak již bylo výše uvedeno, že je podporován v každém moderním internetovém prohlížeči. Není tedy třeba nic instalovat (aspoň v úvodní fázi, kdy nevyžadujeme pokročilé funkcionality) a lze přistoupit přímo ke tvorbě javascriptového kódu.

K zápisu kódu lze využít obyčejný textový editor (např. Notepad ve Windows, TextEdit v MacOS nebo např. Vim v Linuxu), případně lze použít některý specializovaný editor, určený pro psaní programového kódu, z nichž lze doporučit např. Visual Studio Code volně ke stažení na https://code.visualstudio.com/, případně Atom editor, rovněž volně ke stažení na https://atom.io/. Oba dva výše uvedené editory jsou bezplatně k dispozici pro všechny hlavní platformy, tedy Windows, MacOS i Linux a současně jsou vynikající ukázkou funkční aplikace, napsané v JavaScriptu.

První kód, který v JavaScriptu napíšeme, bude tvořit součást webové stránky, kterou zobrazíme v prohlížeči, který následně javascriptový kód interpretuje a zobrazí výsledek.

V editoru (viz výše) si vytvoříme soubor index.html a vložíme do něj následující kód:

Po jeho uložení na disk a spuštění dvojklikem by se měl spustit internetový prohlížeč, který by měl zobrazit text První kód v JavaScriptu, tedy text, který jsme požadovali vypsat příkazem document.write().

Náš první kód samozřejmě nedělá nic jiného než to, že vypíše na obrazovku uvedený text. Z obdobného základu nicméně budeme vycházet, s jistými modifikacemi, i v případech, kdy budeme zamýšlet naprogramovat něco skutečně užitečného.

Abychom ale něco užitečného zvládli naprogramovat, je nutné si osvojit znalost JavaScriptu na alespoň základní úrovni.

Pro úvod můžeme javascriptový program zjednodušeně považovat za část webové stránky, zajišťující její interaktivitu, který je umístěn mezi značkami (dále budeme používat obvyklejší označení tagy) <script> a </script>:

V případě rozsáhlejších projektů se javascriptový kód zpravidla umisťuje do externích souborů. Můžeme tak vytvořit např. soubor main.js, do kterého budeme zapisovat náš kód, zde již bez tagů <script> a </script>

Program pak načteme z externího souboru do našeho hlavního souboru index.html tak, že v souboru index.html definujeme tagy <script> a </script> s uvedením adresy externího souboru main.js:

Celý soubor index.html s načtením externího souboru main.js tedy bude vypadat takto:

Další, pokročilou možností, jak načítat kód z externího souboru, jsou moduly a jejich importy, nicméně s touto možnosti se seznámíme až v některém z dalších dílů.

Proměnné jsou, společně s operátory, základními stavebními kameny každého programovacího jazyka. Jejich prostřednictvím se odehrává zadávání instrukcí, které má počítač provést. Pomocí proměnných si pro náš program vyhrazujeme místo v paměti počítače, do kterého lze ukládat hodnoty a dále s nimi pracovat. Proměnné v JavaScriptu nemají (zásadně) žádný typ, tudíž do jedné proměnné lze postupně uložit číslo, textový řetězec, logickou hodnotu a z pohledu běhu programu takový postup nevyvolá ani chybu, ani varování. Proto se o jazyku JavaScript někdy hovoří také jako o beztypovém, díky této vlastnosti se jedná o jazyk poměrně intuitivní, na druhou stranu, v rozsáhlejších projektech tato vlastnost může být, a často také je, zdrojem chyb.

Deklarace proměnných

Abychom proměnné mohli používat v našem programu, je nejprve nutné je deklarovat. To lze učinit pomocí klíčových slov var, let nebo const. Deklaraci proměnných pomocí klíčového slova var použijeme asi nejčastěji. Pro začátek nám postačí vědět, že na rozdíl od deklarace pomocí klíčového slova let nám vytvoří tzv. globální proměnnou, tedy proměnnou, na kterou budeme "vidět" z kteréhokoli místa našeho programu.

Všiměnete si:
  • Na řádku 1 jsme definovali proměnnou a bez přiřazení hodnoty.
  • na řádku 2 jsme definovali proměnnou b, které jsme přiřadili hodnotu 5.
  • Na řádku 3 jsme definovali proměnnou c, které jsme přiřadili hodnotu "pozdrav".

Kromě beztypovosti má JavaScript ještě jednu vlastnost, která jej činí sice intuitivním, ale na druhou stranu i jazykem náchylným k chybám (což nicméně není primárně problém tohoto jazyka, chyby stále mají svůj původ mezi klávesnicí a židlí). JavaScript totiž umožňuje pracovat i s nedefinovanými proměnnými. Pokud tedy za běhu programu přiřadíme libovolnou hodnotu např. proměnné c, kterou jsme ale předtím nedefinovali, nevyvolá takový postup žádné chybové hlášení ani varování, což zejména v případě větších projektů může způsobit zanesení obtížně odhalitelné chyby do kódu programu. Proto (a nejen proto) byl postupem času vytvořen tzv. striktní režim, který v případě použití nedeklarovaných proměnných vyvolá chybové hlášení. Striktní režim se aktivuje pomocí deklarace "use strict" Následující postup nevyvolá chybové hlášení:

Přestože na řádku 2 přiřazujeme k nedefinované proměnnéc proměnnou a, přiřazení proběhne a hodnota proměnné c bude nyní 5.

Následující postup již ale chybové hlášení vyvolá, protože aktivujeme striktní režim interpretace kódu:

Nyní by již přiřazení do proměnné c na řádku 3 mělo vyvolat chybu, protože na řádku 1 jsme deklarovali přísný režim interpreatace.

Prostřednictvím klíčového slova const se nedefinují proměnné, ale konstanty, jejich podstatným rozdílem oproti proměnným je, že je po jejich deklaraci již nelze za běhu programu měnit. Následující postup nevyvolá chybové hlášení, protože proměnnou pi jsme deklarovali pomocí klíčového slova var.

Deklarace, které jsme provedli na řádcích 1 až 3, jsou v pořádku, proměnná pi bude postupně nabývat hodnot, které jsme jí přiřadili. Oproti tomu přiřazení, která jsme provedli na řádcích 5 až 8, již chybu vyvolají, protože se jimi snažíme změnit hodnotu definované konstanty phi, což není přípustné.

Již výše bylo uvedeno, že operátory jsou, společně s proměnnými, základními stavebními kameny každého programovacího jazyka. Použitím jedné nebo více proměnných a operátoru dostaneme výraz, který nám data z použitých proměnných zpracuje do nové hodnoty, se kterou lze dále pracovat.

Přiřazení

Přiřazení je základní operací s proměnnými. Přiřazení se provádí operátorem =. V rámci tohoto článku jsme se s přiřazením již setkali a pro rekapitulaci uvádím následující příklad:

Na řádku 1 jsme deklarovali proměnnou a a přiřadili jí hodnotu 5, dále jsme na řádku 2 deklarovali proměnnou b a přiřadili jí hodnotu 3. Na řádku 3 jsme deklarovali proměnnou c a přiřadili jí hodnotu součtu proměnných a + b, tedy hodnotu 8.

Sčítání, odčítání, násobení, dělení

Obdobně jako přiřazení fungují i operátory pro sčítání +, odčítání -, násobení * a dělení /

Kromě uvedených základních aritmetických operátorů existují ještě další, které si případně vysvětlíme v dalších dílech.

Operátory pro práci s textovými řetězci

Jako právníci pracujeme s texty. Proto pro nás budou významné operátory, které se uplatní při práci s textovými řetězci. Textové hodnoty uvozujeme buď jednoduchými uvozovkami '' nebo dvojitými uvozovkami "". Standard z roku 2015 (ES6) zavedl dále tzv. šablonové řetězce (template literals), které umožňují do řetězce vkládat výrazy, které se přímo v řetězci vyhodnotí. To přináší výhody především při programování šablon, ve kterých se mezi formátovací kód vkládají výrazy, což doposud bylo nutné činit velmi nepřehledným způsobem. Šablonové řetězce uvozujeme zpětnými uvozovkami (tzv. backtickem) ``.

Všiměnete si:
  • Na řádku 5 jsme sečetli proměnné a + b. Protože tyto proměnné neobsahují mezeru, bude výsledek, uložený v proměnné c, rovněž bez mezer.
  • Na řádku 7 provádíme sčítání tří hodnot, a to hodnoty proměnné a, prázdného řetězce
    " " a hodnoty proměnné b.

U šablonových řetězců lze přímo do řetezce vložit výraz, který se sám vyhodnotí. Použitý výraz je nutné vložit mezi uvozovací znaky ${}:

Všimněte si:
  • Na řádku 4 jsme deklarovali více proměnných, tak, že za klíčovým slovem var jich uvedeme více s tím, že je oddělíme čárkou.
  • Šablonové řetězce, jak můžeme vidět na řádku 6, jsou, zejména u delších textů, přehlednější, než běžné řetezce na řádku 9.

Funkce nám umožňují organizovat náš kód do bloků, čímž jej činí přehlednějším. Funkce lze za běhu programu opakovaně vyvolat, tudíž pro stejnou funkcionalitu, potřebnou na různých místech programu, není nutné opisovat stále stejný kód, ale postačí zavolat příslušnou funkci, což přispívá ke zvýšení efektivity při programování.

Deklarace funkce

Funkci v javascriptu definujeme pomocí klíčového slova function, která je následována názvem funkce a dále závorkami (). V závorkách mohou být uvedeny názvy vstupních parametrů, se kterými má funkce pracovat. Kód, který má být funkcí vykonán, se píše mezi blok tvořený složenými závorkami {}. Deklarujeme funkci naDruhou() a jedním vstupním parametrem cislo.

Volání funkce

Jednou deklarovanou funkci v kódu voláme prostřednictvím jejího názvu následovaného závorkami s argumenty, tedy vstupními hodnotami, které funkci předáváme. U výše deklarované funkce naDruhou() bude její volání vypadat následovně:

Všimněte si:
  • Parametr lze funkce předat buď jako pevně zapsané číslo, jak vidíme na řádku č. 2, což ale není příliš praktické.
  • Daleko častěji se parametr funkci předává v proměnné, jak můžeme vidět na řádku č. 5.

Návratová hodnota funkce

Funkce má praktický význam pouze tehdy, pokud umožňuje výstup své činnosti za běhu programu předat dále. To se děje pomocí klíčového slova return, které kromě toho, že vrátí zadanou hodnotu jako výsledek funkce, zároveň běh funkce ukončí (tudíž nemá smysl za klíčové slovo return dále něco psát, protože takový kód se nevykoná).

S funkcemi JavaScript umožňuje provádět velká kouzla. Ne všechny je z důvodu zachování přehlednosti budeme probírat. Je nicméně dobré vědět, že každá funkce si vytváří svůj blok, v rámci kterého lze definovat vlastní proměnné (tzv. block scope). Kromě proměnných definovaných v bloku funkce můžeme z funkce přistupovat i k proměnným definovaným v globálním prostoru pomocí klíčového slova var. Je dokonce možné, aby v rámci globálního prostoru byla deklarována proměnná se stejným názvem, jako proměnná v prostoru funkce, přičemž tyto proměnné se vzájemně neovlivní.

Všimněte si:
  • Na řádku č. 1 jsme definovali proměnnou x = 5, která je platná globálně pro celý program.
  • Funkce alert(), kterou voláme na řádcích č. 2, 7 a 11, slouží k vypsání zadaného parametru, v tomto případě hodnoty proměnné x.
  • Proměnná x, deklarovaná na řádku č. 6, je jiná proměnná, než proměnná x, deklarovaná na řádku č. 1. Její platnost je omezena pouze na rozsah funkce test().
  • Proto funkce alert(), volaná na řádku č. 2 a řádku č. 11, vypíše hodnotu 5, zatímco funkce alert(), volaná na řádku č. 7, vypíše hodnotu 2.
  • Pokud bychom na řádku č. 6 na místo deklarace var x = 2 provedli jen přiřazení x = 2, změnili bychom hodnotu přímo globální proměnné x.

Řízení toku programu se v JavasSriptu děje nejčastěji přes podmínkßy a přepínače. Ty nám umožňují za běhu programu vyhodnotit stav vybraných proměnných a na základě toho rozhodnout o dalším průběhu provádění programu.

Podmínky

Podmínky definujeme pomocí klíčových slov if ... else, případně if ... else if ... else a za pomoci porovnávacích operátorů je rovno ==, není rovno !=, větší než >, menší než <, vetší nebo rovno >= a menší nebo rovno <=. Základní definice podmínky by tedy mohla vypadat následovně:

Všimněte si:
  • Vypíše se proměnná x je rovna 5.

Poněkud složitější podmínka by mohla vypadat následovně:

Všimněte si:
  • Vypíše se proměnná x je větší než 3.

Přepínače

Přepínače slouží k vyhodnocení složitějších možností. Jsou definovány pomocí klíčových slov switch, case, default a break. Přepínač uvozujeme klíčovým slovem switch, následují definice jednotlivých případů (možností), uvozených klíčovým slovem case. Každý případ musíme ukončit klíčovým slovem break, což je důležité, protože jinak by se kód prováděl až do okamžiku, než by narazil na klíčové slovo break v rámci jiného case nebo dokud by neproběhl do konce přepínače. Klíčové slovo default používáme pro ošetření případů, pro které nepředvídáme žádné specifické řešení, lze si to představit jako sběrnou kategorii.

Všimněte si:
  • Vypíše se Hodinová sazba advokáta je 3.000,- Kč.

Smyčky

Smyčky slouží k provádění opakovaných činností. Jsou definovány pomocí klíčových slov for, while, for ... in a do ... while.

Zřejmě nejpoužívanější je smyčka definovaná pomocí klíčového slova for Za ním následující závorky, do kterých se zpravidla zapisují 3 parametry. První, který se vykoná jednou před spuštěním smyčky, druhý, který definuje podmínku, při jejímž plnění smyčka probíhá, a třetí, který se vykoná vždy po proběhnutí jednoho kola při běhu smyčky:

Všimněte si:
  • Na řádku č. 1 jsme si jako první parametr smyčky definovali proměnnou i, kterou jsme inicializovali na hodnotu 0.
  • Jako druhý parametr smyčky jsme sid efinovali podmínku, která se bude kontrolovat při každém průběhu smyčky, a to, že proměnná i musí být menší < než 5.
  • Po průběhu každé smyčky se proměnná i zvýší o 1 tzv. autoinkrementací i++.
  • Postupně se vypíší hodnoty 04.

Nejjednodušší je smyčka definovaná pomocí klíčového slova while. Za ním následující závorky, do kterých se zapisuje 1 parametr, a to podmínka, při jejímž plnění smyčka probíhá:

Všimněte si:
  • Smyčka bude probíhat, dokud proměnná i bude menší < než 10.
  • Na konci smyčky je nutné vždy provést autoinkrementaci proměnné i. Je také možné její hodnotu nastavovat jinak (např. snižovat), čímž lze ovlivňovat průběh smyčky.

Struktury pro práci s daty jsou objekty, které si můžeme představit jako složitější proměnné, které nám umožňují organizovaným způsobem pracovat s většími objemy dat. Jejich základními typy jsou pole Array a objekty Object.

Pole

Pole je často využívanou datovou strukturou, kterou můžeme definovat obdobně jako proměnnou s tím, že jí přiřadíme hodnotu uvozenou hranatými závorkami [], do kterých zapíšeme jednotlivé hodnoty, oddělené od sebe čárkami. Základní definice pole může vypadat např. následovně:

K hodnotám definovaným v poli musíme nějakým způsobem přistupovat. To můžeme učinit prostřednictvím indexu pole, který standardně narůstá od 0. Pro začátek je dobré si uvědomit, že index pole ovoce opravdu začíná od 0, tudíž pokud chceme přistoupit k prvnímu prvku pole ("občan"), musíme použít index 0, nikoli index 1.

Všimněte si:
  • Přes index 0 na řádku č. 2 vypíšeme hodnotu občan.
  • Přes index 3(ve skutečnosti jde o čtvrtou položku, protože první je 0) na řádku č. 3 vypíšeme hodnotu správa.
  • Obdobným způsobem lze přes indexy do pole zapisovat. Zápisem na řádku č. 4 na index 2 změníme hodnotu pole na příslušném indexu z trest na obchod.

K hodnotám definovaným v poli lze přistupovat i ve smyčce, pomocí metody forEach, která je vlastní každému poli (metoda je funkce, ale protože je zavěšena na objektu, říká se jí metoda). Jako parametr metody forEach je nutné předat funkci, kterou bude smyčka při každém jejím průběhu volat. Anglický název pro tuto funkce je callback, český ekvivalent neexistuje, nicméně zřejmě by takovou funkci bylo možné nazývat jako odvolávkovou.

Všimněte si:
  • Postupně se vypíší všechny hodnoty pole obory.

Objekty

Objekty jsou další často využívanou datovou strukturou. Přesněji řečeno, terminologicky správně bychom měli hovořit o tzv. objektových literálech, protože JavaScript ze své koncepce považuje za objekt doslova vše (tím si ale nyní nebudeme plést hlavu). Objektový literál můžeme opět definovat obdobně jako proměnnou s tím, že jí přiřadíme hodnotu uvozenou složenými závorkami {}, do kterých zapíšeme páry klíč : hodnota, oddělené od sebe čárkami. Základní definice objektového literálu může vypadat např. následovně:

I k hodnotám definovaným v objektu se musíme nějakým způsobem dostat. K tomu lze typicky použít buď název objektu, následovaný tečkou . a názvem klíče, případně název objektu, následovaný hranatými závorkami s názvem klíče, uvedeným v uvozovkách ['klic'].

K hodnotám definovaným v objektovém literálu lze rovněž přistupovat i ve smyčce, pomocí smyčky for ... in. Základní implementace je poměrně jednoduchá, nicméně objektové literály lze definovat i jako vložené (tedy objektový literál bude jedním z prvků jiného objektového literálu) a na tyto vložené objektové literály by již následující základní implementace nedostačovala:

Interakce s uživatelem v zásadě slouží pro vkládání parametrů nutných pro běh programu a vypsání výstupu (nejlépe způsobem pro uživatele srozumitelným). Pro obsluhu interakce s uživatelem si již nevystačíme pouze se samotným JavaScriptem, ale budeme muset zapojit i některé prvky značkovacího jazyka HTML, pomocí kterého se ve webových aplikacích tvoří uživatelské rozhraní.

Pro přehlednost použijeme pouze několik málo formátovacích značek, a to INPUT, pomocí kterého ošetříme vstupy od uživatele, dále DIV, pomocí kterého zajistíme vypsání výstupů uživateli a konečně BUTTON, kterým ošetříme potvrzení akce ze strany uživatele.

Nejprve pomocí formátovací značky INPUT vytvoříme uživatelský vstup a přiřadíme mu název vstup1. Následně pomocí formátovací značky DIV vytvoříme výstup a přiřadíme mu název vystup1. A nakonec pomocí formátovací značky BUTTON vytvoříme tlačítko, kterým budeme potvrzovat akci uživatele a přiřadíme mu název tlacitko1. K tlačítku přiřadíme funkci osetrivstup(). Nyní ještě musíme přidal blok SCRIPT abychom v něm deklarovali funkci osetrivstup(), kterou jsme přiřadili k události kliknutí na tlačítko tlacitko1. Funkce osetrivstup() nebude dělat nic jiného, než že načte hodnotu ze vstupu vstup1 a vypíše ji na výstup vystup1.

Všimněte si:
  • K jednotlivým prvkům uživatelského rozhraní můžeme z našeho programu přistupovat pomocí metody getElementById() objektu document, který v JavaScriptu slouží k manipulaci s DOM (Dokumentovým Objektovým Modelem), prostřednictvím kterého webový prohlížeč vykresluje obsah stránky.
  • Jako parametr metody getElementById() zadáváme identifikátor, kterým jsme označili náš prvek v rámci zadání formátovací značky. Pokud jsme tedy definovali vstup <input id="vstup1"></input>, potom je třeba jako parametr předat hodnotu "vstup1".

Na závěr jsem zvolil jako ukázku něčeho praktického jednoduchý kalkulátor soudního poplatku, stanoveného procentem ze základu, vyjádřeného peněžní částkou.

Program bude fungovat tak, že bude vycházet z následujících předpokladů: (i) základ poplatku se zaokrouhluje na celá sta korun dolů, (ii) vypočtený poplatek se pak zaokrouhluje na celé desítky korun nahoru, (iii) u základu do částky 20.000,- Kč včetně bude poplatek činit 1.000,- Kč, (iv) u základu od částky 20.000,- Kč do 40.000.000,- Kč činí poplatek 5 %, (v) u základu od částky 40.000.000,- Kč do 250.000.000,- Kč činí poplatek 2.000.000,- Kč + 1 % z částky přesahující 40.000.000,- Kč, (vi) částka základu nad 250.000.000,- Kč se ve výpočtu poplatku nezohledňuje.

Nejprve si definujeme potřebné vstupy, v daném případě to bude pouze základ poplatku v Kč. Vytvoříme si základní kostru programu, která se bude skládat ze souboru index.html, obsahujícího vizuální rozhraní našeho programu, a dále soubor main.js, který bude obsahovat kód, zajišťující jeho funkcionalitu.

Do souboru index.html tedy vložíme základní strukturu HTML souboru, jak jsme se s ní seznámili již výše a doplníme ji o formulář pro vstup, tlačítko pro potvrzení vstupů a dále zobrazení výstupu.

Dále budeme editovat kód v souboru main.js. Deklarujeme funkci spocitej(), kterou jsme navázali na událost kliknutí na tlačítko.