> Как обратиться к объекту и пройти по цепочке прототипов в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Сбер
Стек: JavaScript
> Пример ответа
Короткий ответ
Чтобы обратиться к объекту и пройти по цепочке прототипов в JavaScript, используй Object.getPrototypeOf(obj) для получения прототипа, а затем рекурсивно вызывай его, пока не получишь null. Альтернативно можно использовать __proto__ (не рекомендуется в production) или Reflect.getPrototypeOf. Цепочка заканчивается на Object.prototype, чей прототип - null.
Подробное объяснение
Каждый объект в JavaScript имеет внутреннее свойство [[Prototype]], которое ссылается на другой объект или null. Это формирует цепочку прототипов, используемую для разрешения свойств и методов при обращении через точку или скобки.
Для программного обхода цепочки прототипов используй:
Object.getPrototypeOf(obj)- стандартный, безопасный способ, работает во всех современных средах.Reflect.getPrototypeOf(obj)- аналог, часть Reflect API, возвращает тот же результат.obj.__proto__- устаревший геттер/сеттер, не рекомендуется из-за проблем с производительностью и совместимостью в некоторых edge-случаях.
Процесс обхода: начиная с объекта, получаем его прототип, затем прототип прототипа и так далее, пока не дойдём до null. Это позволяет инспектировать наследование, проверять наличие свойств в цепочке или копировать методы.
Важно: свойство constructor и методы вроде hasOwnProperty находятся в Object.prototype, поэтому они доступны всем объектам через цепочку.
На практике
На собеседовании senior-уровня ожидается не просто знание синтаксиса, а понимание внутреннего механизма и практических применений:
- Проверка наследования:
obj instanceof Constructorиспользует цепочку прототипов, но для прямого обхода лучше использоватьisPrototypeOf. - Клонирование с сохранением прототипа: при создании объекта с тем же прототипом используй
Object.create(Object.getPrototypeOf(obj)). - Полифиллы и метапрограммирование: обход цепочки нужен для реализации
Object.assignс учётом прототипов или для создания глубоких копий. - Оптимизация: частый обход цепочки может быть медленным, поэтому для проверки собственных свойств используй
hasOwnProperty.
Пример типичной задачи: написать функцию, которая собирает все ключи из цепочки прототипов, исключая встроенные методы Object.prototype.
Пример кода
JAVASCRIPT// Функция для обхода цепочки прототиповfunction walkPrototypeChain(obj) {const chain = [];let current = obj;while (current !== null) {chain.push(current);current = Object.getPrototypeOf(current);}return chain;}// Пример использованияconst parent = { a: 1 };const child = Object.create(parent);child.b = 2;const protoChain = walkPrototypeChain(child);console.log(protoChain); // [child, parent, Object.prototype, null]// Проверка наличия свойства во всей цепочкеfunction hasPropertyInChain(obj, prop) {let current = obj;while (current !== null) {if (prop in current) return true;current = Object.getPrototypeOf(current);}return false;}console.log(hasPropertyInChain(child, 'a')); // trueconsole.log(hasPropertyInChain(child, 'toString')); // true (из Object.prototype)
Как отвечать на собеседовании
Начни с чёткого определения цепочки прототипов и способов доступа к ней. Упомяни Object.getPrototypeOf как предпочтительный метод. Покажи понимание разницы между собственными и унаследованными свойствами. Приведи пример практического использования - например, для реализации глубокого сравнения объектов или для создания фабричной функции с наследованием.
Избегай излишнего углубления в детали реализации V8 или SpiderMonkey, если не спрашивают. Сфокусируйся на стандарте ECMAScript и практических сценариях.
Что проверяет интервьюер
- Понимание механизма наследования через прототипы, а не классов (даже если используется синтаксис class).
- Умение различать собственные и унаследованные свойства.
- Знание стандартных API для работы с прототипами и их отличий.
- Способность применять эти знания для решения реальных задач (клонирование, проверка типов, метапрограммирование).
- Осознание trade-off между производительностью и удобством при обходе цепочки.
Типичные ошибки
- Использование
__proto__в production-коде без необходимости. - Путаница между
prototype(свойство функции-конструктора) и[[Prototype]](внутреннее свойство объекта). - Предположение, что
Object.prototypeвсегда последний в цепочке - для объектов, созданных черезObject.create(null), цепочка заканчивается наnullсразу. - Забывание, что
for...inпроходит по всей цепочке, а не только по собственным свойствам. - Неправильная обработка
nullпри рекурсивном обходе - отсутствие проверки приводит к ошибке.
> Похожие задачи по frontend
Что такое иммутабельность в JavaScript
Какие ключи могут быть в объекте и в Map в JavaScript
Можно ли забиндить контекст функции в JavaScript и как это сделать
Выполняются ли скрипты в порядке перечисления в документе и работает ли это с async
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью