Условные конструкции: if, else, switch

Условные конструкции if/else и switch управляют потоком выполнения программы, выбирая ветку кода на основе булева условия или сравнения значения с набором вариантов.

Зачем нужно

Условные конструкции — основа любой программной логики. Знание когда предпочесть switch вместо if/else, как использовать тернарный оператор и ?? / || для кратких выражений делает код чище и выразительнее.

Где используется

  • Бизнес-логика: проверка прав, состояний, ролей
  • Валидация данных
  • Роутинг: разные действия для разных URL
  • Обработка ошибок: разные реакции на разные типы

if / else if / else

function getDiscount(user) {
  if (!user) {
    return 0;
  } else if (user.isPremium && user.yearsActive > 3) {
    return 0.3;
  } else if (user.isPremium) {
    return 0.2;
  } else if (user.isNewUser) {
    return 0.1;
  } else {
    return 0;
  }
}

Ранний return вместо вложенного else

// Паттерн guard clause — избегаем вложенности
function processOrder(order) {
  if (!order) return null;
  if (!order.items.length) return { error: 'Корзина пуста' };
  if (!order.user.isVerified) return { error: 'Пользователь не верифицирован' };

  // основная логика — без else
  return completeOrder(order);
}

switch

Удобен для сравнения одного значения с множеством вариантов:

function getDayName(day) {
  switch (day) {
    case 0: return 'Воскресенье';
    case 1: return 'Понедельник';
    case 2: return 'Вторник';
    case 3: return 'Среда';
    case 4: return 'Четверг';
    case 5: return 'Пятница';
    case 6: return 'Суббота';
    default: return 'Неизвестный день';
  }
}

// Группировка case (fall-through)
function isWeekend(day) {
  switch (day) {
    case 0: // воскресенье
    case 6: // суббота
      return true;
    default:
      return false;
  }
}

Тернарный оператор

// Вместо простого if/else
const status = user.isActive ? 'активен' : 'неактивен';

// Встроен в строку
const greeting = `Привет, ${user.isAdmin ? 'администратор' : 'пользователь'}!`;

// Вложенный тернарный — только если читаемо
const role =
  user.isAdmin    ? 'admin' :
  user.isModerator ? 'moderator' :
  'user';

Логические операторы как условия

// || — возвращает первое truthy значение (или последнее)
const name = user.name || 'Аноним';
const port = process.env.PORT || 3000;

// ?? (nullish coalescing) — только null/undefined, не falsy
const count = user.count ?? 0;  // 0 если count === null/undefined
// user.count || 0 даст 0 даже при count=0 — не то же самое!

// && — возвращает первое falsy или последнее значение
const admin = user.isAdmin && user.permissions; // permissions если isAdmin
// В JSX: { isLoading && <Spinner /> }

// ?. (optional chaining) — условный доступ
const city = user?.address?.city ?? 'Не указан';

Object lookup вместо switch

Для простых маппингов:

// Вместо switch с 10+ case
const ACTION_HANDLERS = {
  'increment': (state) => ({ ...state, count: state.count + 1 }),
  'decrement': (state) => ({ ...state, count: state.count - 1 }),
  'reset':     (state) => ({ ...state, count: 0 }),
};

function reducer(state, action) {
  const handler = ACTION_HANDLERS[action.type];
  return handler ? handler(state) : state;
}

Частые ошибки

1. Забытый break в switch (fall-through)

switch (x) {
  case 1:
    doA;
    // Нет break — упадёт в case 2!
  case 2:
    doB; // выполнится при x=1 И x=2
    break;
}

2. switch использует === (строгое сравнение)

const input = '1'; // строка из input.value

switch (input) {
  case 1: // число, не строка — не совпадёт!
    console.log('один');
    break;
}

// Решение: явное приведение или сравнение строк
switch (Number(input)) {
  case 1: console.log('один'); break;
}

3. Вложенные тернарные — нечитаемо

// Плохо:
const x = a ? b ? 1 : 2 : c ? 3 : 4;

// Хорошо: if/else или именованные переменные
let x;
if (a) x = b ? 1 : 2;
else   x = c ? 3 : 4;

Связанные темы

Ресурсы