> Как избежать ошибки при обращении к свойству объекта, если объект undefined? (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Исходный Код

Стек: JavaScript

> Пример ответа

Короткий ответ

Используйте optional chaining (?.) - obj?.prop?.nested. Для дефолтных значений - ?? (nullish coalescing). Для проверки существования свойства - in оператор или hasOwnProperty. В legacy коде - тернарник obj && obj.prop. Избегайте try/catch для простых проверок - это оверхед.

Подробное объяснение

Основные подходы к безопасному доступу к свойствам:

  1. Optional chaining (?.) - современный стандарт ES2020. Прерывает цепочку при null или undefined и возвращает undefined. Работает также с динамическими ключами (obj?.[key]) и вызовами функций (func?.()).

  2. Nullish coalescing (??) - возвращает правый операнд только если левый null или undefined. Отличается от || тем, что не считает 0, '', false за falsy значения.

  3. Логическое И (&&) - классический паттерн obj && obj.prop. Работает, но ломается на falsy значениях (0, пустая строка), если они валидны.

  4. Оператор in - проверяет наличие свойства в объекте (включая прототип). 'prop' in obj - безопасно для любого obj, кроме null/undefined.

  5. hasOwnProperty - проверяет собственные свойства, без прототипа. Лучше вызывать через Object.prototype.hasOwnProperty.call(obj, 'prop') для защиты от переопределения.

  6. Деструктуризация с default - const { prop = defaultValue } = obj || {} - удобно, но создает лишний объект.

На практике

Для вложенных объектов используйте цепочку ?. - это читаемо и безопасно. Комбинируйте с ?? для fallback значений. Избегайте глубоких цепочек - если структура сложная, лучше вынести логику в функцию-геттер или использовать библиотеку типа lodash.get.

При работе с API ответами всегда проверяйте наличие данных перед доступом. Для массивов используйте arr?.[index]. Для вызова методов - obj.method?.().

Пример кода

JAVASCRIPT
// Плохо - может упасть
const city = user.address.city;
// Хорошо - optional chaining
const city = user?.address?.city;
// С дефолтным значением
const city = user?.address?.city ?? 'Unknown';
// Для массивов
const firstItem = arr?.[0];
// Для вызова метода
const result = obj.method?.();
// Проверка существования свойства
if ('city' in (user?.address ?? {})) {
// свойство есть
}
// Безопасная деструктуризация
const { city = 'Unknown' } = user?.address ?? {};

Как отвечать на собеседовании

Начните с optional chaining как основного решения. Упомяните разницу между ?? и ||. Покажите понимание edge cases: falsy значения, прототипное наследование, производительность. Если спросят про legacy - расскажите про паттерн && и lodash.get. Не забудьте упомянуть, что ?. нельзя использовать для левой части присваивания.

Что проверяет интервьюер

  • Знание современных возможностей JS (ES2020+)
  • Понимание разницы между null/undefined и falsy значениями
  • Умение выбирать правильный инструмент под задачу
  • Осведомленность о производительности разных подходов
  • Понимание границ применимости (когда ?. не подходит)

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

  • Использование || вместо ?? - теряются валидные falsy значения
  • Чрезмерное использование ?. там, где объект гарантированно существует - снижает читаемость
  • Попытка использовать ?. в левой части присваивания - синтаксическая ошибка
  • Забывают, что ?. проверяет только null/undefined, а не отсутствие свойства в объекте
  • Использование try/catch для простых проверок - плохая практика из-за оверхеда и скрытия реальных ошибок

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью