Programátoři jsou příliš líní a napsat 6 znaků (IF(){}
) potřebných pro vytvoření IF
podmínky je často až příliš.
//správně if (obj && obj.hasOwnProperty(value)) { return obj.value; } //kratší, ale může selhat return obj.value
Ale skutečně je potřeba psát IF
, nebo postačí nějaký chytrá konstrukce JavaScriptu, který je známý svou laxností k syntaxy?
Ternární výraz
IF-ELSE
lze snadno nahradit ternárním výrazem (nebo také YES-NO
podmínka). Často se používá v případě, že se vám nechce plýtvat 5 řádky na správný zápis celého IF-ELSE
:
//IF-ELSE if (podmínka) { YES } else { NO } //YES-NO (podmínka ? YES : NO);
Výhoda YES-NO
zápisu je v tom, že nejde o příkaz, ale o výraz, takže ho lze použít i v přiřazení, jako parametr funkce, apod.
//IF-ELSE if (podmínka) { funkce('YES'); } else { funkce('NO'); } //YES-NO value = (podmínka ? 'YES' : 'NO'); funkce(podmínka ? 'YES' : 'NO');
Binární výrazy
Podmínky je možno psát i pomocí binárních OR
a AND
; díky tomu, že JavaScript tak netrpí na typy proměnných a výrazů, nemusí být výsledkem binárního výrazu binární hodnota:
//většina jazyků bool1 = (value1 || value2); bool2 = (value1 && value2); //JavaScript mixed1 = (value1 || value2); mixed2 = (value1 && value2);
Výsledkem binárního výrazu v JavaScriptu je vždy poslední hodnota, která byla ve výrazu použita:
a = null; b = ''; c = 0; x = (a || b || c); //x je 0 (číslo nula) y = (a && b && c); //y je null z = (a || b && c); //z je '' (prázdný řetezec)
K tomu dochází proto, že JavaScript (při použití &&
a ||
) provádí neúplné vyhodnocení a tudíž v okamžiku, kdy je již zcela jasný výsledek podmínky (false && cokoliv = false; true || cokoliv = true
), dál již nic neprování.
Díky tomu můžete místo IF
nebo YES-NO
použít přímo OR
nebo AND
:
//IF-ELSE if (obj instanceof MyArray) { value = processArray(obj); } else if (Arr instanceof Array) { value = processArray(Arr); } else { value = processArray([]); } //YES-NO value = obj ? processArray(obj) : Arr ? processArray(Arr) : processArray([]); //Binární výraz value = processArray(obj || Arr || []);
Binární příkaz
JavaScript si ani moc nedělá hlavu s rozdílem mezi výrazem a příkazem. Z jakéhokoliv výrazu můžete vytvořit příkaz tím, že ho uzavřete do závorek a zakončíte středníkem:
//Ostatní jazyky: false; //chybná syntaxe //JavaScript false; //validátor může upozornit na chybu, // ale lze spustit //JavaScript správně (false); //OK
Samozřejmě použít false
jako příkaz je nesmysl podobně jako podmínka if(false)
, ale v mnoha případech lze této konverze využít:
//IF if (jQuery) { jQuery(document).myPlugin(); } //YES-NO (jQuery ? jQuery(document).myPlugin() : undefined ); //Binární příkaz (jQuery && jQuery(document).myPlugin());
Všechny tři tyto příkazy dělají to samé – zavolají myPlugin
pokud je ve stránce načtena knihovna jQuery.
Podmínka IF
to provede jako obvykle – zkontroluje existenci proměnné jQuery
(což je znak toho, že je jQuery načteno) a pak provede příslušný příkaz.
Ternární výraz provádí to samé jen s tím rozdílem, že do NO
větve dáme undefined
, což znamená, že se nic nestane (i když to samé vy provedla jakákoliv jiná hodnota jako null
, false
, true
, 0
, 1
, atd.). Zde je sice YES-NO
výraz uveden na 4 řádkách, takže zdánlivě není o nic kratší než IF
, ale to je jen omezení tohoto webu – v programu může být klidně uveden na jedné řádce pro úsporu místa.
Binární výraz posouvá podmínku na novou úroveň tím, že použije AND
operátor a v případě, že proměnná jQuery
neexistuje, je výsledkem levé části podmínky FALSE
a tudíž se již pravá část nevyhodnocuje (a nedojde tedy k zavolání metody).
Často se této metody používá pro ověření parametrů funkce nebo nastavení výchozí hodnoty parametru:
function alert(message, showIcon, options) { options = options || {} message = message || options.message || 'Chyba'; showIcon = (false !== showIcon); //... }
Pokud neuvedeme showIcon
, použije se výchozí hodnota True
(protože undefined
není rovno false
). Pokud vynecháme options
, použijeme místo toho prázdný objekt. Díky tomu pak můžeme použít i podmínku pro zprávu, kde pokud není definován přímo message
, zkusí se použít vlastnost message
z options
a pokud options.message
neexistuje, zobrazí se jen „Chyba“.
Pozor na false
Při psaní jednoduchých podmínek pozor na to, co vše se vyhodnotí jako false
:
(undefined || {}); //{}; undefined == false (null || {}); //{}; null == false (0 || 1); // 1; 0 == false ('' || 'nic'); //'nic'; '' == false ([] || null); //[]; [] == true ({} || null); //{}; {} == true (1/0 || -1); //Infinity (0/0 || -1); //-1; NaN == false (Boolean(false) || null); //Boolean(false)
U poslední řádky je potřeba dát pozor na to, že jakýkoliv objekt se vždy vyhodnotí jako true
, i když reprezentuje jednoduchou hodnotu, která by měla být vyhodnocena jako false
!