Оператор 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 делает однотипные ветвления чище, если использовать его по назначению.