Když je IF moc dlouhý

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!

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..