Как работает optional chaining `?.` и nullish coalescing `??` в JavaScript?

JuniorJavaScript · Frontend·Обновлено 31 июля 2026
Коротко
Optional chaining ?. позволяет безопасно обращаться к свойствам объекта без проверки на null/undefined, возвращая undefined вместо ошибки. Nullish coalescing ?? возвращает правый операнд, если левый равен null или undefined.

Optional chaining ?.

Оператор ?. позволяет обращаться к вложенным свойствам объекта, не проверяя каждый уровень вручную на существование. Если значение слева от ?. равно null или undefined, выражение немедленно возвращает undefined вместо того, чтобы выбросить TypeError.

Синтаксис

obj?.prop          // доступ к свойству
obj?.[expr]        // доступ через скобки
obj?.method()      // вызов метода
arr?.[index]       // доступ к элементу массива

Пример без optional chaining

// Старый способ — приходится проверять каждый уровень
const city = user && user.address && user.address.city;

Пример с optional chaining

const city = user?.address?.city; // undefined, если user или address отсутствует

?. «замыкает» всю цепочку: как только встречается null/undefined, вычисление останавливается и возвращается undefined.

Nullish coalescing ??

Оператор ?? возвращает левый операнд, если он не равен null или undefined, иначе — правый. Это позволяет задавать значения по умолчанию точнее, чем ||, который считает ложными также 0, '', false.

Отличие ?? от ||

const count = 0;

const a = count || 10;  // 10 — потому что 0 falsy
const b = count ?? 10;  // 0 — потому что 0 не null/undefined

Совместное использование

Операторы отлично работают вместе: ?. обрабатывает отсутствие объекта, ?? подставляет значение по умолчанию.

const timeout = config?.network?.timeout ?? 3000;
// Если config или network отсутствуют — 3000
// Если timeout явно равен 0 — вернётся 0, а не 3000

Вызов необязательных методов

user?.getProfile?.(); // вызовется только если user и getProfile существуют

Важные ограничения

  • ?. нельзя использовать в левой части присваивания: user?.name = 'Ivan' — синтаксическая ошибка.
  • ?? нельзя смешивать с && и || без скобок — это синтаксическая ошибка для явности кода:
// SyntaxError
const x = a || b ?? c;

// Правильно
const x = (a || b) ?? c;

Что хочет услышать интервьюер

Кандидат объясняет, что `?.` останавливает выполнение цепочки при `null`/`undefined` и возвращает `undefined`, а не бросает ошибку

Кандидат понимает разницу между `??` и `||`: `??` реагирует только на `null`/`undefined`, а `||` — на любое falsy-значение

Кандидат приводит практический пример совместного использования `?.` и `??`

Кандидат знает, что `?.` работает не только для свойств, но и для вызовов методов и обращений по индексу

Кандидат упоминает ограничение: `?.` нельзя ставить слева от присваивания

Пример: Optional chaining и nullish coalescing на практике

// Данные пользователя могут быть неполными
interface User {
  name: string;
  address?: {
    city?: string;
    zip?: string;
  };
  getAge?: () => number;
}

const user: User = { name: 'Иван' };

// Optional chaining — безопасный доступ к вложенным свойствам
const city = user?.address?.city;       // undefined (без ошибки)
const zip  = user?.address?.zip;        // undefined

// Вызов необязательного метода
const age = user?.getAge?.();           // undefined (метод отсутствует)

// Nullish coalescing — значение по умолчанию только для null/undefined
const displayCity = city ?? 'Не указан';  // 'Не указан'

// Разница ?? vs ||
const score = 0;
console.log(score || 100);  // 100 — некорректно, 0 является валидным результатом
console.log(score ?? 100);  // 0  — правильно

// Совместное использование
const config = { timeout: 0 };
const timeout = (config as any)?.network?.timeout ?? 5000;
console.log(timeout); // 5000, т.к. network отсутствует

Типичные ошибки

Путают `??` с `||` и используют `||` там, где `0`, `''` или `false` являются корректными значениями

Думают, что `?.` защищает от всех ошибок — не учитывают, что он проверяет только `null`/`undefined`, а не другие некорректные значения

Злоупотребляют `?.` везде подряд, маскируя реальные баги вместо того чтобы исправить источник проблемы

Забывают, что смешивать `??` с `&&`/`||` без скобок — синтаксическая ошибка

Пытаются присвоить значение через `?.` в левой части выражения

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее