switch

Інструкція switch обчислює вираз, зіставляє значення виразу зі значенням блоку case та виконує інструкції, що відносяться до цього блоку, а також інструкції у блоках case, наступних за блоком, що має збіг.

Синтаксис

switch (expression) {
  case value1:
    //Інструкції, що виконуються, коли
    //результат виразу збігається з value1
    [break;]
  case value2:
    //Інструкції, що виконуються, коли
    //результат виразу збігається з value2
    [break;]
  ...
  case valueN:
    //Інструкції, що виконуються, коли
    //результат виразу збігається з valueN
    [break;]
  [default:
    //Інструкції, що виконуються, коли жодне
    //значення не збігається зі значенням виразу
    [break;]]
}
expression
Вираз, чий результат зіставляється з кожним блоком case.
case valueN Optional
Блок case, який зіставляється з виразом expression. Якщо значення expression збігається з вказаним значенням valueN, інструкції всередині блоку case виконуються, поки не досягнуть або кінця інструкції switch, або оператора break.
default Optional
Блок default; якщо вказаний, виконується у випадку, коли значення expression не збігається з жодним з блоків case.

Опис

Інструкція switch спочатку обчислює вираз. Далі шукає перший блок case, чий вираз має таке саме значення, що й результат вхідного виразу (використовуючи строгу рівність, ===) та передає контроль цьому блоку, виконуючи інструкції, що до нього відносяться. (Якщо більше одного case збігаються з наданим значенням, обирається перший знайдений case, навіть якщо блоки case не дорівнюють одне одному.)

Якщо не знайдено жодного збігу серед блоків case, програма шукає необов'язковий блок default, і, якщо знаходить, передає йому контроль, виконуючи відповідні інструкції. Якщо блоку default не знайдено, програма продовжує виконання першої з інструкції, що йде після завершення switch. Прийнято писати блок default останнім, але це не обов'язково.

Необов'язковий оператор break у кожному case гарантує, що програма перериває виконання switch, як тільки виконані знайдені інструкції, та продовжує виконання з інструкції, що йде після switch. Якщо break не вказано, програма продовжує виконання наступної інструкції у switch.

Приклади

Використання switch

У наступному прикладі, якщо expr дорівнює Банани, програма знаходить збіг з блоком case 'Банани' та виконує відповідну інструкцію. Дійшовши до оператора break, програма перериває виконання switch та виконує інструкцію, наступну після switch. Якби не оператор break, інструкція блоку case 'Вишні' також би виконалась.

switch (expr) {
  case 'Апельсини':
    console.log('Апельсини коштують $0.59 за фунт.');
    break;
  case 'Яблука':
    console.log('Яблука коштують $0.32 за фунт.');
    break;
  case 'Банани':
    console.log('Банани коштують $0.48 за фунт.');
    break;
  case 'Вишні':
    console.log('Вишні коштують $3.00 за фунт.');
    break;
  case 'Манго':
  case 'Папайя':
    console.log('Манго та папайя коштують $2.79 за фунт.');
    break;
  default:
    console.log('Вибачте, в нас закінчились ' + expr + '.');
}

console.log("Бажаєте чого-небудь ще?");

Що станеться, якщо я забуду break?

Якщо ви забудете break, скрипт буде виконуватись, починаючи від блоку, який відповідає умові, і продовжить виконувати наступні блоки, незалежно від того, чи відповідають вони умові.

Дивіться наступний приклад:

var foo = 0;
switch (foo) {
  case -1:
    console.log('від\'ємна 1');
    break;
  case 0: // foo дорівнює 0, отже, умова виконана, і цей блок виконається
    console.log(0);
    // ЗАУВАГА: забутий break стояв би тут
  case 1: // немає оператора break у 'case 0:', тому цей блок також виконається
    console.log(1);
    break; // програма зустріне тут break і не виконуватиме 'case 2:'
  case 2:
    console.log(2);
    break;
  default:
    console.log('default');
}

Чи можна поставити default між блоками case?

Так, можна! JavaScript відправить вас у default, якщо не знайде збігів:

var foo = 5;
switch (foo) {
  case 2:
    console.log(2);
    break; // програма зустріне тут break, і не виконуватиме 'default:'
  default:
    console.log('default')
    // проходимо далі
  case 1:  
    console.log('1');
}

Це також працює, якщо поставити default перед усіма блоками case.

Методи для кількох критеріїв case

Джерело цієї техніки тут:

Інструкція switch з кількома блоками case у JavaScript (Stack Overflow)

Декілька case : одна операція

Цей метод використовує переваги того факту, що, якщо в кінці блоку case немає оператора break, він продовжить виконувати наступний блок case, незалежно від того, чи той відповідає необхідній умові. (Дивіться розділ Що станеться, якщо я забуду break?)

Ось приклад інструкції для єдиної операції з послідовних case, де чотири різні значення виконують одне й те саме.

var Animal = 'Жирафа';
switch (Animal) {
  case 'Корова':
  case 'Жирафа':
  case 'Собака':
  case 'Свиня':
    console.log('Ці тварини підуть на Ноїв ковчег.');
    break;
  case 'Динозавр':
  default:
    console.log('Ця тварина не піде.');
}

Декілька case : ланцюгові операції

Ось приклад кількох операцій у послідовних блоках case, де, в залежності від наданого цілого числа, ви можете отримати різний результат. Він демонструє, що виконуватиметься у тому порядку, в якому ви розташували блоки case, і вони не обов'язково мають бути чисельно послідовні. У JavaScript ви навіть можете змішувати їх з рядковими значеннями.

var foo = 1;
var output = 'Результат: ';
switch (foo) {
  case 0:
    output += 'То ';
  case 1:
    output += 'як ';
  case 2:
    output += 'тебе ';
  case 3:
    output += 'звати';
  case 4:
    output += '?';
    console.log(output);
    break;
  case 5:
    output += '!';
    console.log(output);
    break;
  default:
    console.log('Будь ласка, оберіть число від 0 до 5!');
}

Результат цього прикладу:

Значення Виведений текст
foo дорівнює NaN або не 1, 2, 3, 4, 5 чи 0 Будь ласка, оберіть число від 0 до 5!
0 Результат: То як тебе звати?
1 Результат: як тебе звати?
2 Результат: тебе звати?
3 Результат: звати?
4 Результат: ?
5 Результат: !

Змінні блочної області видимості у інструкціях switch

Маючи підтримку ECMAScript 2015 (ES6) у більшості сучасних веб-переглядачів, у певних випадках ви захочете використати оператори let та const для оголошення змінних блочної області видимості.

Погляньте на цей приклад:

const action = 'скажи_привіт';
switch (action) {
  case 'скажи_привіт':
    let message = 'привіт';
    console.log(message);
    break;
  case 'скажи_бувай':
    let message = 'бувай';
    console.log(message);
    break;
  default:
    console.log('Отримана порожня дія.');
    break;
}

Цей приклад спричинить помилку Uncaught SyntaxError: Identifier 'message' has already been declared, яку ви, можливо, не очікували.

Все тому, що перше оголошення let message = 'привіт'; конфліктує з другим оголошенням let message = 'бувай'; хоча вони й розташовані у окремих блоках case 'скажи_привіт': та case 'скажи_бувай':. Зрештою, це відбувається тому, що обидва оголошення let інтерпретуються як дублюючі оголошення однієї змінної всередині тієї самої блочної області видимості.

Ми можемо легко це виправити, огорнувши наші блоки case у дужки:

const action = 'скажи_привіт';
switch (action) {
  case 'скажи_привіт': { // додані дужки
    let message = 'привіт';
    console.log(message);
    break;
  } // додані дужки
  case 'скажи_бувай': { // додані дужки
    let message = 'бувай';
    console.log(message);
    break;
  } // додані дужки
  default: { // додані дужки
    console.log('Отримана порожня дія.');
    break;
  } // додані дужки
}

Тепер цей код, як і задумано, виведе у консоль привіт без жодних помилок.

Специфікації

Специфікація
ECMAScript (ECMA-262)
The definition of 'switch statement' in that specification.

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
switchChrome Full support 1Edge Full support 12Firefox Full support 1IE Full support 4Opera Full support 4Safari Full support 1WebView Android Full support 1Chrome Android Full support 18Firefox Android Full support 4Opera Android Full support 10.1Safari iOS Full support 1Samsung Internet Android Full support 1.0nodejs Full support 0.1.100

Legend

Full support  
Full support

Див. також