Оператор switch
Оператор switch
Технический фундамент switch
switch - это конструкция множественного выбора по одному выражению. Она полезна, когда нужно сравнить одно значение с набором фиксированных вариантов и выполнить соответствующую ветку.
Ключевая механика:
- выражение в
switch (...)вычисляется один раз; - сравнение с
caseидет строго через===; - если совпадения нет, выполняется
default(если он есть).
function tokenType(ch) {
switch (ch) {
case '(':
return 'paren-open';
case ')':
return 'paren-close';
default:
return 'other';
}
}
Этот пример показывает чистую техническую роль switch: однозначно сопоставить значение входа с одним из дискретных кейсов.
Когда switch лучше, чем цепочка if/else
switch удобен, когда ты сравниваешь одно значение с несколькими фиксированными вариантами: статус заказа, роль пользователя, тип действия, язык интерфейса.
Ключевой момент: switch делает однотипные проверки компактнее и структурнее, чем длинная лестница if/else if.
Проверь себя: почему switch не подходит для сложных диапазонов вроде score > 70 && score < 90?
Базовый синтаксис
switch (expression) {
case value1:
// код
break;
case value2:
// код
break;
default:
// fallback
}
expression сравнивается с case через строгое сравнение (===).
Смотри, что важно: типы должны совпадать ('1' не равно 1).
Роль break
Без break выполнение "проваливается" в следующий case (fallthrough).
const role = 'admin';
switch (role) {
case 'admin':
console.log('Панель админа');
break;
case 'user':
console.log('Панель пользователя');
break;
default:
console.log('Гость');
}
Здесь часто путаются: забытый break может привести к выполнению лишней ветки.
Еще один частый сюрприз: case сам по себе не создает отдельный блок области видимости. Поэтому let/const, объявленные в одном case, конфликтуют с таким же именем в другом case.
Анти-провал: если нужно объявлять переменные внутри case, оборачивай тело кейса в {}.
switch (role) {
case 'admin': {
const panel = 'admin panel';
console.log(panel);
break;
}
case 'user': {
const panel = 'user panel';
console.log(panel);
break;
}
default:
console.log('guest');
}
default как обязательный fallback
default срабатывает, когда ни один case не подошел.
function getOrderLabel(status) {
switch (status) {
case 'new':
return 'Новый';
case 'paid':
return 'Оплачен';
case 'shipped':
return 'Отправлен';
default:
return 'Неизвестный статус';
}
}
Анти-провал: всегда оставляй fallback-ветку, особенно для данных из API.
Проверь себя: что произойдет, если сервер пришлет новый статус, а default нет?
Группировка кейсов
Можно объединять несколько вариантов в один результат.
switch (code) {
case 200:
case 201:
message = 'Успех';
break;
case 400:
case 404:
message = 'Ошибка клиента';
break;
default:
message = 'Другая ошибка';
}
Это полезно для классов похожих состояний.
Мини-сценарий: режим интерфейса
function getThemeLabel(mode) {
switch (mode) {
case 'light':
return 'Светлая тема';
case 'dark':
return 'Темная тема';
case 'system':
return 'Системная тема';
default:
return 'Тема не задана';
}
}
Четкое перечисление значений делает поведение предсказуемым.
Частые ошибки новичков
- Забывать
breakв середине блока. - Не добавлять
default. - Передавать значения другого типа (
numberвместоstring). - Использовать
switchтам, где логика зависит от сложных условий, а не от одного значения.
Анти-провал: перед switch нормализуй вход (тип, регистр строки), чтобы сравнение по === работало стабильно.
Что будет, если изменить входные данные
Если в getOrderLabel передать 'paid', вернется ожидаемый текст. Если придет 'PAID', не сработает ни один case, потому что строка отличается регистром. Значит, иногда нужен status.toLowerCase() до switch.
Проверь себя: почему нормализация входа до switch снижает число неожиданных default?
Краткий итог
switchудобен для сравнения одного значения с набором фиксированных вариантов.- Сравнение идет строго (
===), поэтому тип и формат входа критичны. breakпредотвращает нежелательный fallthrough.defaultобязателен как безопасный fallback.switchделает однотипные ветвления чище, если использовать его по назначению.