Menu
Русский

switch в JavaScript: case, break и fallthrough

Разбираем оператор switch в JavaScript: как работают case, break, default, что такое проваливание (fallthrough) и когда switch удобнее цепочки if/else.

Switch в JavaScript: выбор одной ветки из многих

Оператор switch в js пригодится, когда нужно сравнить одно и то же значение с набором заранее известных вариантов. Формально ту же задачу решает цепочка if/else if/else, но как только вы в третий-четвёртый раз подряд проверяете одну и ту же переменную, switch читается заметно приятнее.

Базовый синтаксис выглядит так:

index.js
Output
Click Run to see the output here.

Если читать этот код сверху вниз, получается следующее: JavaScript вычисляет day, сравнивает со значением каждого case и выполняет подходящий блок. default срабатывает, когда ничего не совпало — это как финальный else. Порядок чтения такой: значениеcaseкод.

Как на самом деле работает сравнение в switch

switch сравнивает строго — оператором ===. Никакого приведения типов, никаких «почти совпадений». case 1: сработает для числа 1, но не для строки "1".

index.js
Output
Click Run to see the output here.

Совпадает только второй case. Если вдруг ваш switch не срабатывает там, где должен, — в 99% случаев виноват несовпадающий тип: строка вместо числа, прилетевшая из формы или URL-параметра.

break — это то, что останавливает выполнение

Вот здесь как раз и подстерегает большинство разработчиков. Метка case — это точка перехода, а не самостоятельный блок. Как только выполнение попало в подходящий case, оно идёт дальше построчно — прямо сквозь метки следующих case, — пока не наткнётся на break, return или конец switch.

Посмотрите, что будет без break:

index.js
Output
Click Run to see the output here.

Совпадение — "editor", но в консоли ты видишь сразу может редактировать, может просматривать и вошёл в систему. Это и есть fallthrough: выполнение «проваливается» в следующие case, потому что его ничто не останавливает.

Добавляем break — и всё работает как надо:

index.js
Output
Click Run to see the output here.

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

Осознанный fallthrough: группируем case

Fallthrough в switch — это не всегда баг. Пропуск break — аккуратный способ сказать «все эти варианты делают одно и то же»:

index.js
Output
Click Run to see the output here.

Если поставить подряд несколько пустых меток case, все они будут делить один и тот же блок кода ниже. Обратите внимание: после return писать break не нужно — функция и так завершится. return внутри switch сразу выходит из него, пропуская всё, что шло дальше.

А вот когда fallthrough между непустыми case действительно нужен намеренно — обязательно оставьте комментарий, иначе следующий разработчик решит, что это баг, и «починит»:

index.js
Output
Click Run to see the output here.

default не обязан быть в конце

По традиции default ставят в самом низу — именно там его и ожидают увидеть большинство читающих код. Но с технической точки зрения это просто ещё одна метка: она срабатывает, когда ни один case не подошёл, причём независимо от места в блоке. Если воткнуть default где-нибудь посередине и забыть break, выполнение провалится (fallthrough) в следующий за ним блок. Ставьте default последним, закрывайте его break (или не закрывайте — дальше всё равно ничего нет), и ваше будущее «я» скажет спасибо.

index.js
Output
Click Run to see the output here.

Область видимости переменных внутри case

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

switch (x) {
    case 1:
        let msg = "one";
        break;
    case 2:
        let msg = "two";   // SyntaxError: Identifier 'msg' has already been declared
        break;
}

Решение простое — оборачиваем тело каждого case в блок { }:

index.js
Output
Click Run to see the output here.

Теперь каждое msg живёт в своей области видимости, и конфликт исчезает. Это стоит держать в голове всякий раз, когда в case появляется чуть больше логики, чем одна-две строки.

switch или if/else в JavaScript

Оператор switch хорош, когда нужно сверить одно значение с множеством фиксированных вариантов: HTTP-коды, типы экшенов в Redux, имена команд, строки-перечисления. Проверяемое значение указывается один раз в самом верху, а список case читается как оглавление — взгляд легко пробегает по вариантам.

if/else удобнее в таких случаях:

  • Вы сравниваете диапазоны (score >= 90, score >= 75).
  • В условиях участвуют разные переменные или булевы выражения.
  • Нужно нестрогое равенство или своя логика сравнения (switch всегда работает через ===).
index.js
Output
Click Run to see the output here.

Современной альтернативой для первого варианта часто служит поиск по объекту:

index.js
Output
Click Run to see the output here.

Три строки вместо девятистрочного switch. Когда кейсы — это просто сопоставление данных без какой-либо логики, объект (или Map) обычно читается лучше. switch имеет смысл брать тогда, когда в каждом case реально что-то происходит.

Дальше: циклы for

switch помогает сделать один выбор из множества вариантов. Следующий кирпичик управления потоком — повторение, то есть прогон одного и того же блока кода снова и снова. Именно для этого нужны циклы for, о которых и пойдёт речь дальше.

Часто задаваемые вопросы

Как работает оператор switch в JavaScript?

switch сравнивает одно значение с набором меток case, используя строгое равенство (===). Как только находится совпадение, выполняется код этой ветки и продолжает выполняться дальше — пока не встретится break или не закончится блок. Если ни один case не подошёл, срабатывает необязательная ветка default.

Что такое fallthrough (проваливание) в switch?

Если в конце case нет break (или return), выполнение «проваливается» в следующий case и выполняет его код — даже если метка не совпала. Иногда это полезно, чтобы объединить несколько веток с общей логикой, но чаще это просто баг. Правило простое: ставьте break в конце каждого case, если только fallthrough не нужен вам осознанно.

Когда лучше использовать switch, а когда if/else?

switch удобен, когда одно значение сравнивается с кучей фиксированных вариантов — HTTP-статусы, типы экшенов в Redux, строковые команды. if/else выбирайте, если нужны диапазоны, несколько переменных или логические выражения. И не забывайте: switch работает через строгое равенство, поэтому case '1' не поймает число 1.

Учитесь программировать с Coddy

НАЧАТЬ