switch: выбор из многих вариантов

ветвления≈ 6 минут

Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.

Когда одну и ту же переменную нужно сравнить с целым списком значений, цепочка if...else if начинает повторяться. switch говорит «сравниваю вот это» один раз — но взамен требует помнить про строгое сравнение и break.

Разделы темы:·

В скобках после switch стоит выражение — его вычисляют один раз. Дальше идёт тело в фигурных скобках, а в нём метки case со значениями для сравнения.

Найдено совпадение — выполнение прыгает на эту метку и идёт вниз, пока не встретит break. Важно понимать именно так: case — это не «ветка-коробочка», а точка входа.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Тело ветки может быть любой длины — обычно его пишут с новой строки и отступом. В одну строку варианты складывают только когда они короткие, как в примере выше.

Значения сравниваются строго, как оператором ===. Строка "2" и число 2 — два разных варианта, и «похожесть» здесь не работает.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

После case можно писать не только литерал, но и любое выражение — оно вычисляется в момент проверки. Правда, злоупотреблять этим не стоит: читателю кода придётся считать в уме.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Всё, что пришло из поля ввода или из адреса страницы, — строка. Хотите сравнивать с числами — сначала преобразуйте: Number(value).

break выходит из switch. Без него выполнение не останавливается на границе ветки, а «проваливается» в следующую — и в следующую за ней, пока не встретит break или не кончится тело. Причём условия соседних case уже не проверяются: код просто выполняется подряд.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Если switch стоит внутри функции, вместо break часто пишут return — он и ветку завершает, и результат отдаёт.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Тело switch — один общий блок, а case внутри него лишь метки. Поэтому два const с одним именем в разных ветках — это переобъявление в одной области видимости и ошибка ещё до запуска. Лечится собственными фигурными скобками у каждой ветки.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Раз проваливание существует, его можно использовать намеренно. Метка без тела передаёт управление следующей — так несколько разных значений ведут в один и тот же код.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Это единственный вид проваливания, который читается без вопросов. Если же вы сознательно роняете выполнение из непустой ветки в следующую, оставьте комментарий — иначе следующий читатель решит, что вы забыли break.

Ветка default срабатывает, когда ни одно значение не подошло — тот же смысл, что у финального else. Она необязательна: без неё несовпадение просто ничего не делает, и это молчание нередко оказывается настоящей ошибкой в программе.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Привычка ставить default хотя бы с сообщением об ошибке экономит часы отладки: неизвестное значение сразу заявляет о себе, а не растворяется в тишине.

Формально default — такая же метка, как case. Её можно поставить в середину: тогда при несовпадении выполнение прыгнет туда и провалится в идущие ниже ветки. Так пишут крайне редко, но встретить в чужом коде можно.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

switch выигрывает у цепочки if там, где проверяется равенство одного и того же значения трём и более вариантам: имя переменной пишется один раз, а варианты выстраиваются в столбик. Как только в условиях появляются диапазоны, && или сравнения — это работа для if. Приём switch (true) с условиями в case формально работает, но читается хуже обычной цепочки.

А если каждая ветка не делает ничего, кроме «этому ключу соответствует вот это значение», то и switch избыточен — достаточно объекта-словаря.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
Что происходит в веткахЧем писать
Равенство одного значения, в ветках — действияswitch
Диапазоны, несколько условий, сравненияцепочка if
Ключ просто отображается в значениеобъект-словарь

  • switch вычисляет выражение один раз и сравнивает его с метками case строго, как ===
  • case — не отдельный блок, а точка входа: без break выполнение проваливается в следующие ветки
  • Пустые case подряд — законный способ объединить несколько значений в одну ветку
  • default ловит всё, что не совпало; без него несовпадение проходит молча
  • Если ветки только возвращают значения, объект-словарь короче switch, а для диапазонов и сложных условий остаётся if

1/3В переменной лежит строка "3". Выполнится ли ветка case 3?

2/3Что будет, если в ветке case забыть break?

3/3В каком случае объект-словарь удобнее switch?

Рабочий день или выходной

Напишите функцию dayType(day): она получает номер дня недели (1 — понедельник, 7 — воскресенье) и возвращает строку "выходной" для 6 и 7, иначе "рабочий". Используйте switch с группировкой меток.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Метки 6 и 7 идут подряд и ведут в один код, всё остальное забирает default. Внутри функции вместо break удобнее return: он и завершает ветку, и отдаёт результат.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Переписать switch словарём

Перед вами switch, ветки которого только возвращают значения. Перепишите функцию через объект-словарь, сохранив поведение — включая ответ "?" для неизвестного кода.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Словарь объявляем снаружи функции, чтобы объект не создавался заново при каждом вызове. Роль default берёт на себя ??: если такого ключа нет, обращение вернёт undefined и сработает запасное значение.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.