Конструкція switch може замінити кілька if.
Вона дає можливість більш наочного способу порівняння значення відразу з кількома варіантами.
Конструкція switch має один або більше case блоків та необов'язковий блок default.
Вона виглядає так:
switch(x) {
case 'value1': // if (x === 'value1')
...
[break]
case 'value2': // if (x === 'value2')
...
[break]
default:
...
[break]
}- Значення змінної
xперевіряється на строгу рівність (=== ) значенню із першого блокуcase(яке дорівнюєvalue1), потім значенню із другого блоку (value2) і так далі. - Якщо строго рівне значення знайдено, то
switchпочинає виконання коду із відповідногоcaseдо найближчогоbreakабо до кінця всієї конструкціїswitch. - Якщо жодне
case- значення не збігається - виконується код із блокуdefault(якщо він присутній).
Приклад використання switch (код який буде виконаний виділено):
let a = 2 + 2;
switch (a) {
case 3:
alert( 'Замало' );
break;
*!*
case 4:
alert( 'Точнісінько!' );
break;
*/!*
case 5:
alert( 'Забагато' );
break;
default:
alert( 'Я не знаю таких значень' );
}Тут switch починає порівнювати a з першим варіантом із case, який дорівнює 3. Це не відповідає a.
Потім з другим, який дорівнює 4. Цей варіант відповідає a, таким чином буде виконано код з case 4 до найближчого break.
Якщо break відсутній, то буде продовжено виконання коду наступних блоків case без перевірок.
Приклад без break:
let a = 2 + 2;
switch (a) {
case 3:
alert( 'Замало' );
*!*
case 4:
alert( 'Точнісінько!' );
case 5:
alert( 'Забагато' );
default:
alert( 'Я не знаю таких значень' );
*/!*
}В прикладі вище ми бачимо послідовне виконання трьох alert:
alert( 'Точнісінько!' );
alert( 'Забагато' );
alert( 'Я не знаю таких значень' );````smart header="Будь-який вираз може бути аргументом switch/case"
Обидва `switch` та `case` допускають будь-який вираз в якості аргументу.
Наприклад:
let a = "1";
let b = 0;
switch (+a) {
*!*
case b + 1:
alert("виконано це, бо +a це 1, що строго дорівнює b + 1");
break;
*/!*
default:
alert("це не буде виконано");
}Тут значення виразу +a буде 1, що збігається з значенням виразу b + 1 із блоку case, таким чином код із цього блоку буде виконано.
## Групування "case"
Кілька варіантів блоку `case`, які використовують однаковий код, можуть бути згруповані.
Наприклад, якщо ми бажаємо виконати один і той самий код для `case 3` та `case 5`:
```js run no-beautify
let a = 3;
switch (a) {
case 4:
alert('Вірно!');
break;
*!*
case 3: // (*) групуємо два блоки `case`
case 5:
alert('Невірно!');
alert("Можливо вам варто відвідати урок математики?");
break;
*/!*
default:
alert('Результат виглядає дивно. Дійсно.');
}
```
Тепер обидва варіанти `3` та `5` виводять однакове повідомлення.
Можливість групування блоків `case` -- це побічний ефект того, як `switch/case` працює без `break`. Тут виконання коду `case 3` починається з рядка `(*)` та проходить через `case 5`, бо немає `break`.
## Тип має значення
Необхідно наголосити, що перевірка відповідності є завжди строгою. Значення повинні бути однакового типу аби вони збігалися.
Наприклад, розглянемо наступний код:
```js run
let arg = prompt("Введіть значення?");
switch (arg) {
case '0':
case '1':
alert( 'Один або нуль' );
break;
case '2':
alert( 'Два' );
break;
case 3:
alert( 'Ніколи не буде виконано!' );
break;
default:
alert( 'Невідоме значення' );
}
```
1. Для `0` та `1` буде виконано перший `alert`.
2. Для `2` - другий `alert`.
3. Але для `3`: результат виконання `prompt` є строкове значення `"3"`, яке строго не дорівнює `===` числу `3`. Таким чином ми маємо "мертвий код" в блоці `case 3`! Буде виконано код блоку `default`.