switch: выбор по точному значению

В переменной size – размер одежды: одна из строк 'XS', 'S', 'M'. Для каждого значения нужно вывести свою подпись – три точных значения, три ответа. Через if..else получается цепочка:

sizes-if.jsjs
const size = 'M';if (size === 'XS') {  console.log('очень маленький');} else if (size === 'S') {  console.log('маленький');} else if (size === 'M') {  console.log('средний');} else {  console.log('такого размера нет');}
Консоль
средний

Работает, но читается тяжело: три раза повторяется переменная, три раза – оператор ===, а различаются ветки только значением в скобках. Когда одно значение нужно сверить с перечнем точных вариантов, в языке есть отдельная конструкция – switch. Вот та же задача в новой записи:

sizes.jsjs
const size = 'M';switch (size) {  case 'XS':    console.log('очень маленький');    break;  case 'S':    console.log('маленький');    break;  case 'M':    console.log('средний');    break;  default:    console.log('такого размера нет');}
Консоль
средний

Разберём запись. В круглых скобках после слова switch стоит выражение – здесь это переменная size. В фигурных скобках – тело: ветки case. Каждая начинается строкой вида case 'XS': – слово case, значение, двоеточие, – а ниже идёт код ветки. Работает это так:

  1. Выражение в скобках вычисляется – один раз.
  2. Его результат сравнивается со значением каждого case сверху вниз. Сравнение – строгое ===: без приведения типов.
  3. Нашлось совпадение – выполнение начинается с этой ветки и идёт до break, который завершает switch.
  4. Не совпал ни один case – выполняется ветка default. Если её нет, не срабатывает ни одна ветка: выполнение продолжается с кода после закрывающей скобки switch.

Этот проход по шагам:

switch: сравнение до первого совпадения
const size = 'M';
В size – строка 'M'.
switch (size) {
case 'XS':
console.log('очень маленький');
break;
case 'S':
console.log('маленький');
break;
case 'M':
console.log('средний');
break;
default:
console.log('такого размера нет');
}
Консоль
Нет вывода в консоль.

break: точка выхода

case задаёт только вход; break останавливает выполнение.

no-break.jsjs
const size = 'S';switch (size) {  case 'XS':    console.log('очень маленький');  case 'S':    console.log('маленький');  case 'M':    console.log('средний');  default:    console.log('такого размера нет');}
Консоль
маленький
средний
такого размера нет

Здесь ни в одной ветке нет break – и в консоли три строки вместо одной. case задаёт только точку входа, а не отдельную ветку: выполнение начинается с совпавшего case и без break просто течёт вниз, через все следующие ветки. Это называют проваливанием. Заметьте: case 'M' и default выполнились, хотя значение 'S' с ними не сравнивалось – сравнение закончилось на точке входа.

Поэтому break ставят в конце каждой ветки. В последней он формально не нужен, но его пишут тоже: ветка, дописанная ниже, ничего не сломает.

Без break: проваливание вниз
const size = 'S';
switch (size) {
Теперь в size'S', и ни в одной ветке нет break.
case 'XS':
console.log('очень маленький');
case 'S':
console.log('маленький');
case 'M':
console.log('средний');
default:
console.log('такого размера нет');
}

Когда совпадения нет

default подхватывает несовпавшие значения; сравнение с case строгое – тип важен.

default: ни один не совпал

default.jsjs
const size = 'XL';switch (size) {  case 'XS':    console.log('очень маленький');    break;  case 'S':    console.log('маленький');    break;  case 'M':    console.log('средний');    break;  default:    console.log('такого размера нет');}
Консоль
такого размера нет

В переменной size теперь значение 'XL': оно не совпало ни с одним case – выполнилась ветка default. Она подхватывает все значения, которых нет в перечне, и обычно стоит последней: читается как «все остальные случаи». Ветка не обязательна: без default несовпавшее значение просто ничего не запустит, и программа продолжится после switch.

Сравнение строгое: тип важен

typed.jsjs
// значение из поля ввода – строкаconst input = '2';switch (input) {  case 1: console.log('первый'); break;  case 2: console.log('второй'); break;  default: console.log('вариант не найден');}
Консоль
вариант не найден

Строка '2' не совпала с числом 2: case сравнивает строго, без приведения типов – сработал default. Тип важен: данные из полей ввода приходят строками, и переводить их в число нужно до сравнения.

В скобках switch при этом может стоять не только переменная, а любое выражение – оно вычислится один раз, и сравниваться будет его результат:

typed-fix.jsjs
const input = '2';// выражение: строка переведена в числоswitch (Number(input)) {  case 1: console.log('первый'); break;  case 2: console.log('второй'); break;  default: console.log('вариант не найден');}
Консоль
второй

Группировка case

Несколько точек входа в один код – единственное уместное проваливание.

order-status.jsjs
const status = 'shipped';switch (status) {  case 'paid':  case 'shipped':    console.log('заказ в работе');    break;  case 'delivered':    console.log('заказ завершён');    break;  default:    console.log('неизвестный статус');}
Консоль
заказ в работе

У case 'paid': нет своего тела – выполнение проваливается вниз, до общего кода: «заказ в работе» печатается и для 'paid', и для 'shipped'. Несколько case подряд – несколько точек входа в одну ветку.

Такое проваливание между case намеренное и пустое: между сгруппированными case ничего не пишут.

controls.jsjs
const key = 'ArrowUp';switch (key) {  case 'w':  case 'ArrowUp':    console.log('вверх');    break;  case 's':  case 'ArrowDown':    console.log('вниз');    break;}
Консоль
вверх
Одна команда на две клавиши: и буква 'w', и стрелка 'ArrowUp' ведут в общую ветку. default не нужен: прочие клавиши ничего не делают.

if..else или switch: что выбрать

Перечень точных значений – switch; диапазоны и составные условия – if.

Инструменты пересекаются, и выбор между ними – про читаемость. switch уместен в одном сценарии: одна переменная сравнивается с перечнем точных значений – коды, размеры, названия команд. Перечень читается как таблица, и добавить вариант – одна ветка.

if..else – инструмент общего назначения, и он единственный выбор, когда условия – диапазоны (score >= 90), разные переменные или составные проверки с &&: в case такое не записать, он сравнивает только на строгое равенство.

На практике if..else встречается заметно чаще. Если сомневаетесь – начинайте с него, а на switch переходите, когда цепочка else if (x === ...) по одной переменной разрослась.

choose.jsjs
const lang = 'ru';// перечень точных значений одной переменной – удобен switch:switch (lang) {  case 'ru': console.log('Привет'); break;  case 'en': console.log('Hello'); break;  default: console.log('нет перевода');}const age = 20;const hasTicket = true;// диапазоны и составные условия – только if:if (age >= 18 && hasTicket) {  console.log('проходите');}
Консоль
Привет
проходите

// теперь вы знаете

  1. В скобках switch – любое выражение: оно вычисляется один раз, дальше сравнивается результат
  2. case – точка входа: без break выполнение проваливается вниз по веткам
  3. default подхватывает несовпавшие значения; без него несовпавшее значение просто ничего не запускает
  4. Сравнение с case – строгое ===: строка '2' не совпадёт с числом 2
  5. Несколько case подряд без тела – группировка: несколько входов в общий код
  6. switch – для перечня точных значений; диапазоны и составные условия – if

Проверьте себя

Из switch убрали оба break. Что попадёт в консоль при size = 'M'?

const size = 'M';
switch (size) {
case 'S':
console.log('маленький');
case 'M':
console.log('средний');
default:
console.log('такого размера нет');
}

Что попадёт в консоль?

const value = 1;
switch (value) {
case '1':
console.log('совпало');
break;
default:
console.log('не совпало');
}
переключают уроки · не работают при фокусе в полях ввода