13. července 2022

Příkaz „switch“

Příkaz switch dokáže nahradit několik podmíněných příkazů if.

Poskytuje přehlednější způsob, jak porovnat hodnotu s několika variantami.

Syntaxe

Příkaz switch obsahuje jeden nebo více bloků case a nepovinný blok default.

Vypadá to takto:

switch(x) {
  case 'hodnota1':  // if (x === 'hodnota1')
    ...
    [break]

  case 'hodnota2':  // if (x === 'hodnota2')
    ...
    [break]

  default:
    ...
    [break]
}
  • Je ověřena striktní rovnost hodnoty x s hodnotou z prvního case (tj. hodnota1), pak s druhou hodnota2, a tak dále.
  • Pokud je rovnost nalezena, switch začne vykonávat kód od odpovídajícího case až do nejbližšího break (nebo do konce bloku switch).
  • Není-li nalezena žádná rovnost, je vykonán kód default (pokud je uveden).

Příklad

Příklad příkazu switch (vykonaný kód je zvýrazněn):

let a = 2 + 2;

switch (a) {
  case 3:
    alert( 'Příliš málo' );
    break;
  case 4:
    alert( 'Přesně!' );
    break;
  case 5:
    alert( 'Příliš mnoho' );
    break;
  default:
    alert( "Takové hodnoty neznám" );
}

Zde switch začne porovnávat a od první varianty, kterou je 3. Porovnání neuspěje.

Pak 4. Tady je nalezena shoda, takže se začne vykonávat kód obsažený v case 4 a skončí na nejbližším break.

Není-li přítomen příkaz break, spustí se kód v dalších case bez jakéhokoliv porovnání.

Příklad bez break:

let a = 2 + 2;

switch (a) {
  case 3:
    alert( 'Příliš málo' );
  case 4:
    alert( 'Přesně!' );
  case 5:
    alert( 'Příliš mnoho' );
  default:
    alert( "Takové hodnoty neznám" );
}

V uvedeném příkladu vidíme sekvenční vykonání tří alertů:

alert( 'Přesně!' );
alert( 'Příliš mnoho' );
alert( "Takové hodnoty neznám" );
Argumentem switch/case může být jakýkoli výraz

Jak switch, tak case dovolují libovolné výrazy.

Příklad:

let a = "1";
let b = 0;

switch (+a) {
  case b + 1:
    alert("toto se vykoná, protože +a je 1, což se rovná b+1");
    break;

  default:
    alert("toto se nevykoná");
}

Zde +a dává 1, to se v case porovná s b + 1 a spustí se příslušný kód.

Seskupování „case“

Je možné seskupit několik case variant, které mají mít stejný kód.

Například když chceme, aby se stejný kód spustil pro case 3 a case 5:

let a = 3;

switch (a) {
  case 4:
    alert('Správně!');
    break;

  case 3: // (*) dvě seskupené varianty
  case 5:
    alert('Špatně!');
    alert("Proč nenavštěvujete kurz matematiky?");
    break;

  default:
    alert('Tento výsledek je divný. Opravdu.');
}

Nyní 3 a 5 zobrazí stejnou zprávu.

Schopnost „seskupovat“ varianty je vedlejší efekt toho, jak switch/case funguje bez break. Zde provádění case 3 začne od řádku (*) a projde přes case 5, protože tam není žádný break.

Na datovém typu záleží

Zdůrazňujeme, že ověření rovnosti je vždy striktní. Aby se hodnoty rovnaly, musí být stejného typu.

Jako příklad poslouží tento kód:

let arg = prompt("Zadejte hodnotu");
switch (arg) {
  case '0':
  case '1':
    alert( 'Jedna nebo nula' );
    break;

  case '2':
    alert( 'Dvě' );
    break;

  case 3:
    alert( 'Toto se nikdy nevykoná!' );
    break;
  default:
    alert( 'Neznámá hodnota' );
}
  1. Pro 0 a 1 se spustí první alert.
  2. Pro 2 se spustí druhý alert.
  3. Avšak pro 3 je výsledkem příkazu prompt řetězec "3", který není striktně roven === číslu 3. Proto jsme pro case 3 získali mrtvý kód! Spustí se varianta default.

Úlohy

důležitost: 5

Přepište tento kód pomocí if..else, které nahradí následující switch:

switch (prohlížeč) {
  case 'Edge':
    alert( "Vy máte Edge!" );
    break;

  case 'Chrome':
  case 'Firefox':
  case 'Safari':
  case 'Opera':
    alert( 'V pořádku, tyto prohlížeče také podporujeme' );
    break;

  default:
    alert( 'Doufáme, že tato stránka vypadá dobře!' );
}

Abychom dosáhli přesné funkcionality příkazu switch, musí if používat striktní rovnost '==='.

V tomto případě však pro zadané řetězce funguje i obyčejné '=='.

if(prohlížeč == 'Edge') {
  alert("Vy máte Edge!");
} else if (prohlížeč == 'Chrome'
 || prohlížeč == 'Firefox'
 || prohlížeč == 'Safari'
 || prohlížeč == 'Opera') {
  alert( 'V pořádku, tyto prohlížeče také podporujeme' );
} else {
  alert( 'Doufáme, že tato stránka vypadá dobře!' );
}

Všimněte si, že konstrukce prohlížeč == 'Chrome' || prohlížeč == 'Firefox' … je pro lepší čitelnost rozdělena do několika řádků.

Ale i přesto je switch jasnější a přehlednější.

důležitost: 4

Přepište uvedený kód pomocí jediného příkazu switch:

let a = +prompt('a?', '');

if (a == 0) {
  alert( 0 );
}
if (a == 1) {
  alert( 1 );
}

if (a == 2 || a == 3) {
  alert( '2,3' );
}

První dvě podmínky můžeme přepsat do samostatné varianty, třetí musí být ve dvou variantách:

let a = +prompt('a?', '');

switch (a) {
  case 0:
    alert( 0 );
    break;

  case 1:
    alert( 1 );
    break;

  case 2:
  case 3:
    alert( '2,3' );
    break;
}

Všimněte si, že break na konci není nezbytný, ale vložili jsme ho tam, aby byl kód zajištěný pro rozšiřování.

Je možné, že v budoucnu budeme chtít přidat další case, například case 4. Kdybychom před něj na konec case 3 zapomněli umístit break, nastala by chyba. Je to tedy určitý druh pojistky.

Mapa tutoriálu

Komentáře

přečtěte si před komentováním…
  • Máte-li návrhy na zlepšení, vytvořte prosím issue na GitHubu nebo pull request místo komentáře.
  • Pokud v článku něčemu nerozumíte, napište prosím, čemu přesně a na kterém místě.
  • Pro vložení několika slov kódu použijte značku <code>, pro několik řádků je obalte značkou <pre>, pro více než 10 řádků vložte odkaz na pískoviště (plnkr, jsbin, codepen…)