Optional chaining (?.) и nullish coalescing (??) в JavaScript: понятное руководство с примерами
Запросы вроде «optional chaining в JavaScript» или «оператор ?? что делает» стабильно в топе у начинающих. И не зря: пара операторов ?. и ?? делает код короче, безопаснее и понятнее. В этом руководстве вы узнаете, когда и как их применять, чего избегать и как комбинировать для максимальной пользы.
Что такое optional chaining (?.)
Optional chaining безопасно обращается к вложенным свойствам и методам: если на любом шаге встречается null или undefined, выражение возвращает undefined вместо падения с ошибкой.
const user = { profile: { name: "Анна" } };
// Безопасный доступ
const city = user?.profile?.address?.city; // undefined, но без ошибки
// Обычный доступ (может бросить TypeError, если profile или address отсутствуют)
// const city = user.profile.address.city;
Важно: ставьте ?. на каждом потенциально «дырявом» шаге. В user?.profile.address.city отработает только первая проверка; если profile есть, но address нет — будет ошибка.
Варианты синтаксиса
- Доступ к свойству:
obj?.prop - Доступ по индексу/ключу:
obj?.[key] - Вызов метода:
obj.method?.(args)— вызовится только еслиmethodсуществует и не равенnull/undefined
const api = {
utils: {
pick(obj, key) { return obj?.[key]; }
}
};
// Вызов метода, если он есть
const result = api.utils.pick?.({ a: 1 }, "a"); // 1
// Безопасное чтение индекса
const first = [10, 20]?.[0]; // 10
Что такое nullish coalescing (??)
Оператор ?? возвращает правую часть, только если левая — null или undefined. В отличие от ||, он не считает 0, пустую строку "" или false поводом подставлять значение по умолчанию.
const count = 0;
const a = count || 10; // 10 (не то, что мы хотели)
const b = count ?? 10; // 0 (корректно, т.к. 0 — валидное значение)
const title = "";
const t1 = title || "Заголовок"; // "Заголовок"
const t2 = title ?? "Заголовок"; // "" (оставляем пустую строку как осознанный выбор)
Комбинируем ?. и ??
Частый паттерн — безопасный доступ с разумным дефолтом.
// Если у пользователя нет аватара — используем заглушку
function getAvatarUrl(user) {
return user?.profile?.avatar ?? "/img/default-avatar.png";
}
// Безопасная длина массива
const len = response?.items?.length ?? 0;
Реальные кейсы из практики
1) Чтение глубоких полей ответа API
const resp = await getData();
const total = resp?.meta?.pagination?.total ?? 0;
const items = resp?.data ?? [];
2) Опциональные колбэки
function save(data, callbacks = {}) {
// Вызовем, только если onStart задан
callbacks.onStart?.();
// ... сохраняем
// Вызовем, только если onSuccess задан
callbacks.onSuccess?.(data);
}
3) Безопасная работа с DOM
const titleEl = document.querySelector(".title");
// Установим текст, если элемент найден
if (titleEl?.textContent !== undefined) {
titleEl.textContent = "Привет, мир!";
}
Частые ошибки и как их избежать
-
Ставите только один ?., а вложенности больше.
Решение: на каждом потенциально пустом шаге используйте?..// Плохо user?.profile.address.city; // Хорошо user?.profile?.address?.city; -
Путаете ?? и ||.
||«съедает» 0, false и пустую строку,??— нет.const limit = config.limit ?? 20; // 0 остаётся 0 -
Проверяете существование значений через if (obj?.prop). Такой тест упадёт для валидных «ложных» значений (0, false, ""). Лучше явно сравнить с
null/undefined.// Вместо так: if (user?.age) { // 0 лет — тоже возраст, но условие не выполнится } // Делайте так: if (user?.age ?? null) { // значение существует (можно дополнительно проверить тип) } -
Вызов не-функции через ?.().
obj.method?.()пропустит вызов, еслиmethodnull/undefined. Но еслиmethodесть, однако это не функция — получите TypeError. Проверяйте тип при необходимости. -
Небезопасные выражения после ?. ESLint-правило
no-unsafe-optional-chainingпомогает ловить ошибки, когда после?.идёт операция, предполагающая, что значение точно не undefined.
Лучшие практики
- Ставьте ?. там, где данные действительно могут отсутствовать (ответ API, опциональный конфиг, пользовательский ввод).
- Используйте ?? для дефолтов, когда только null/undefined означают «нет значения». Для всего остального — сознательные 0, false, "" — дефолт не нужен.
- Комбинируйте ?. и ?? в одну линию, чтобы упростить защитный код.
- Не увлекайтесь: избыточные
?.там, где структура гарантирована, замедляют чтение кода.
Продвинутые трюки
// Удаление свойства, если объект существует
const ok = delete settings?.temp;
// Доступ к длине только если это строка или массив
const len = (Array.isArray(x) || typeof x === "string") ? x.length : undefined;
// С короткой записью и дефолтом
const safeLen = x?.length ?? 0; // осторожно: у объектов без length будет undefined
Поддержка и транспиляция
Операторы ?. и ?? поддерживаются современными браузерами и Node.js. Для старых окружений используйте Babel/TypeScript — плагины давно стабильны. Не существует «полифилла» в чистом виде (это синтаксис), поэтому нужен транспайлер на этапе сборки.
Итоги
Optional chaining и nullish coalescing — быстрый способ сделать код безопаснее к «дырявым» данным и аккуратно расставить значения по умолчанию. Освойте их комбинации, следите за ловушками (|| против ??, достаточное количество ?.) — и ваш базовый JavaScript станет заметно чище.
Хотите системно прокачать основы и перейти к практическим проектам? Загляните в курс: Прокачать навыки в курсе «JavaScript с Нуля до Гуру 2.0» — пошаговая практика, разбор типичных ошибок и личные мини‑проекты.
-
Создано 27.02.2026 17:01:15
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.