Опциональная цепочка и ??
Данные часто приходят неполными: у пользователя нет адреса, у заказа — скидки. Если обратиться к свойству несуществующего объекта, программа остановится с ошибкой. Опциональная цепочка ?. и оператор ?? помогают аккуратно обходить такие места.
Проблема
Обращение к свойству undefined вызывает ошибку TypeError. У пользователя ниже нет свойства address, поэтому попытка прочитать address.city ломает программу:
const user = { name: 'Анна' };
try {
console.log(user.address.city);
} catch (error) {
console.log(error.name); // TypeError
}Оператор ?.
Опциональная цепочка ?. проверяет значение слева. Если там null или undefined, вся цепочка сразу возвращает undefined, а не ошибку:
const user = { name: 'Анна' };
console.log(user.address?.city); // undefinedЕсли же адрес есть, ?. ведёт себя как обычная точка.
Длинные цепочки
?. можно ставить в нескольких местах одной цепочки — там, где значение может отсутствовать:
const order = {
customer: { name: 'Олег', address: { city: 'Рига' } },
};
console.log(order.customer?.address?.city); // Рига
console.log(order.delivery?.date); // undefinedКвадратные скобки и вызов метода
Для квадратных скобок пишут ?.[ ], а для вызова метода, который может отсутствовать, — ?.():
const user = { name: 'Анна', tags: ['admin'] };
console.log(user.tags?.[0]); // admin
console.log(user.sayHi?.()); // undefinedМетода sayHi у объекта нет, поэтому вызов просто пропускается.
Значение по умолчанию: ??
Оператор ?? возвращает правое значение, если левое — null или undefined. Вместе с ?. он даёт запасной вариант на случай, когда данных нет:
const user = { name: 'Анна' };
const city = user.address?.city ?? 'город не указан';
console.log(city); // город не указанЧастая ошибка
Для значений по умолчанию часто пишут ||, но он заменяет любое ложное значение — в том числе 0 и пустую строку. ?? заменяет только null и undefined:
const settings = { volume: 0 };
console.log(settings.volume || 50); // 50
console.log(settings.volume ?? 50); // 0Громкость 0 — нормальное значение, и || его потерял. Ещё один совет: не ставьте ?. везде подряд. Если свойство обязано быть, пусть ошибка покажет, что данные неверны, а не прячется за undefined.