Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

translation(JS): web/javascript/reference/statements/switch #465

Merged
merged 2 commits into from
Jul 22, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 261 additions & 0 deletions files/uk/web/javascript/reference/statements/switch/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
---
title: switch
slug: Web/JavaScript/Reference/Statements/switch
tags:
- JavaScript
- Language feature
- Reference
- Statement
- Web
browser-compat: javascript.statements.switch
---
{{jsSidebar("Statements")}}

Інструкція **`switch`** (перемикач) обчислює [вираз](/uk/docs/Web/JavaScript/Guide/Expressions_and_Operators), зіставляючи значення виразу з умовою пункту `case`, і виконує [інструкції](/uk/docs/Web/JavaScript/Reference/Statements), пов'язані з цим `case`, а також інструкції у всіх пунктів `case`, що стоять після того пункта, котрий дав збіг.

{{EmbedInteractiveExample("pages/js/statement-switch.html", "taller")}}

## Синтаксис

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

- `expression` (вираз)
- : Вираз, результат якого зіставляється зі кожним пунктом `case`.
- `case valueN` (випадок) {{optional_inline}}
- : Пункт `case`, який зіставляється зі виразом `expression`.
Якщо вираз збігається зі вказаним `valueN` — виконуються інструкції всередині `case`, умова якого збіглася, а далі — інструкції всередині всіх пунктів `case`, що знаходяться після пункту, який збігся, аж до завершення інструкції `switch`, або до ключового слова `break` (припинити).
- `default` (усталено) {{optional_inline}}
- : Усталений пункт. Якщо вказаний — то його буде виконано в разі, якщо значення виразу `expression` не збігається зі жодним із пунктів `case`.

## Опис

Спершу інструкція `switch` обчислює свій вираз. Далі вона шукає перший пункт `case`, чий вираз обчислюється до такого самого значення, як і те, що отримане від обчислення вхідного виразу (використовуючи [порівняння на точну рівність](/uk/docs/Web/JavaScript/Reference/Operators), `===`), і передає керування до цього пункту, виконуючи всі описані в ньому інструкції. (Якщо зі переданим значенням збігаються декілька пунктів `case`, обирається перший `case`, що збігся, навіть якщо всі ці пункти не однакові між собою.)

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

Необов'язкова інструкція [`break`](/uk/docs/Web/JavaScript/Reference/Statements/break), асоційована зі кожною міткою `case`, гарантує, що програма зупиняється і виходить зі `switch` як тільки відповідні інструкції було виконано, і продовжує виконання з наступної слідом за `switch` інструкції. Якщо `break` упущено, програма продовжує виконання зі наступної інструкції всередині інструкції `switch`. Інструкція [`break`](/uk/docs/Web/JavaScript/Reference/Statements/break) не обов'язкова, якщо поперед неї стоїть інструкція [`return`](/uk/docs/Web/JavaScript/Reference/Statements/return).

## Приклади

### Застосування `switch`

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

```js
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`, то скрипт продовжить виконання від пункту `case`, який підійшов під критерій, і продовжить виконувати наступні пункти **незалежно від їхньої відповідності критерію**.

Погляньмо на приклад нижче:

```js
const foo = 0;
switch (foo) {
case -1:
console.log('від\'ємна 1');
break;
case 0: // foo дорівнює 0, а отже – умова має відповідність, тож цей блок буде виконано
console.log(0);
// Примітка: забутий `break` мав би бути тут
case 1: // 'case 0:' не містить інструкції `break`, тому цей випадок теж буде виконано
console.log(1);
break; // програма зустрічає оцей `break`, тож виконання не буде продовжуватись всередину 'case 2:'
case 2:
console.log(2);
break;
default:
console.log('default');
}
```

### Чи можна помістити `default` між іншими випадками?

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

```js
const foo = 5;
switch (foo) {
case 2:
console.log(2);
break; // програма зустрічає оцей `break`, тож виконання не буде продовжуватись всередину 'default:'
default:
console.log('default')
// провалювання
case 1:
console.log('1');
}
```

Це так само працює, якщо поставити `default` перед всіма іншими випадками.

### Способи виконання `case` зі множинними критеріями

Ця техніка також зазвичай називається "провалюванням".

#### Множинні випадки `case`: одинарна операція

Цей метод заснований на тому факті, що за відсутності `break` під пунктом `case` виконання продовжиться наступним пунктом `case` незалежно від того, чи відповідає він критерію. (Детальніше в розділі [Що трапиться, якщо забути `break`](#shcho-trapytsia-yakshcho-zabuty-break))

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

```js
const Animal = 'Жираф';
switch (Animal) {
case 'Корова':
case 'Жираф':
case 'Собака':
case 'Кнур':
console.log('Ця тварина не вимерла.');
break;
case 'Динозавр':
default:
console.log('Ця тварина вимерла.');
}
```

#### Множинні випадки `case`: зв'язані операції

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

```js
const foo = 1;
let output = 'Вивід: ';
switch (foo) {
case 0:
output += 'Отже, ';
case 1:
output += 'Як ';
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` is `NaN` or not `1`, `2`, `3`, `4`, `5`, or `0` | Будь ласка, оберіть число від 0 до 5! |
| `0` | Вивід: Отже, Як Звучить Твоє Ім'я? |
| `1` | Вивід: Як Звучить Твоє Ім'я? |
| `2` | Вивід: Твоє Ім'я? |
| `3` | Вивід: Ім'я? |
| `4` | Вивід: ? |
| `5` | Вивід: ! |

### Змінні блокової області видимості всередині інструкцій `switch`

З огляду на підтримку ECMAScript 2015 (ES6), наявну в більшості сучасних браузерів, будуть траплятися ситуації, коли виникає потреба вжити інструкції {{jsxref("Statements/let", "let")}} і {{jsxref("Statements/const", "const")}}, аби оголосити змінні блокової області видимості.

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

```js
const action = 'say_hello';
switch (action) {
case 'say_hello':
let message = 'Привіт';
console.log(message);
break;
case 'say_hi':
let message = 'Гей';
console.log(message);
break;
default:
console.log('Отримано порожню дію.');
}
```

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

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

Це легко виправити шляхом обгортання цих пунктів `case` у фігурні дужки:

```js
const action = 'say_hello';
switch (action) {
case 'say_hello': { // додано дужки
let message = 'Привіт';
console.log(message);
break;
} // додано дужки
case 'say_hi': { // додано дужки
let message = 'Ей';
console.log(message);
break;
} // додано дужки
default: { // додано дужки
console.log('Отримано порожню дію.');
} // додано дужки
}
```

Цей код виведе `Привіт` у консоль, як і має бути, без жодних помилок взагалі.

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

{{Specifications}}

## Сумісність із браузерами

{{Compat}}

## Дивіться також

- {{jsxref("Statements/if...else", "if...else")}}