Какие данные могут вызвать ошибку при доступе по пути в объекте
Что проверяют
Знаете ли вы точно, когда обращение к свойству бросает исключение, а когда тихо возвращает undefined. Следом просят показать безопасный доступ к вложенным данным из ответа API и спрашивают про разницу между ?? и ||.
Как отвечать
Главное правило: ошибку бросает только чтение свойства у null или undefined. Всё остальное отработает без исключения.
nullиundefinedна пути:user.address.city, гдеaddressне пришёл, даётTypeError: Cannot read properties of undefined. Это самый частый случай с данными из API;- отсутствующее свойство:
obj.missingвернётundefinedбез ошибки, ошибка случится на следующем шаге пути; - примитивы:
(5).fooи"str".barвернутundefined, потому что примитив на время обращения оборачивается в объект. Зато операторinс примитивом бросаетTypeError; - выход за границы массива:
arr[10]вернётundefined, исключения нет; - вызов:
obj.fn(), гдеfnне функция, бросаетTypeError: ... is not a function; - код внутри свойства: геттер или ловушка
Proxyмогут бросить что угодно, отозванныйProxyбросает на любом обращении.
Защита: опциональная цепочка obj?.a?.b и obj.fn?.() (ES2020), значение по умолчанию через ??. Для пути в виде строки "a.b.0.c" берут _.get(obj, path, default) из lodash или свою функцию, которая останавливается на первом null. В TypeScript помогает флаг noUncheckedIndexedAccess, а для данных с сервера схема валидации вроде Zod.
Где спотыкаются
Пишут value || 0 вместо value ?? 0. Оператор || заменит и законные 0, "", false, а ?? реагирует только на null и undefined.
Расставляют ?. на каждом шаге без разбора. Ошибка контракта API не исчезает, а превращается в пустой экран без единой строчки в логах.
Разбирают строковый путь через split(".") и забывают, что ключи бывают с точками. При записи по пути без проверки ключа __proto__ открывается загрязнение прототипа.