> Чем собственные свойства отличаются от унаследованных в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: EvApps
Стек: JavaScript
> Пример ответа
Короткий ответ
Собственные свойства принадлежат самому объекту и определяются через Object.hasOwnProperty() или Object.getOwnPropertyNames(). Унаследованные свойства приходят через prototype chain - они доступны для чтения, но не принадлежат объекту напрямую. Ключевое различие: собственные свойства перечисляются в for...in и учитываются в Object.keys(), а унаследованные - нет. При присваивании значения создаётся собственное свойство, которое перекрывает унаследованное.
Подробное объяснение
Каждый объект в JavaScript имеет внутреннюю ссылку [[Prototype]], которая образует цепочку прототипов. Когда обращаешься к свойству, движок сначала проверяет собственные свойства объекта, затем поднимается по цепочке прототипов до Object.prototype и дальше до null.
Собственные свойства - это те, что определены непосредственно на объекте через литерал, конструктор, Object.defineProperty или присваивание. Они хранятся в внутреннем слоте [[OwnPropertyKeys]] объекта.
Унаследованные свойства - это свойства, найденные в прототипах. Они не создают новых записей в объекте, а лишь доступны через механизм prototype lookup. Важно: унаследованные свойства нельзя перечислить через Object.keys() или Object.getOwnPropertyNames(), но они видны в for...in (если не переопределены).
Различие критично для:
- сериализации (
JSON.stringifyработает только с собственными свойствами) - копирования объектов (shallow copy через spread или
Object.assignне захватывает унаследованное) - проверки наличия свойства (
inоператор учитывает цепочку,hasOwnProperty- нет) - производительности: доступ к унаследованному свойству медленнее, так как требует обхода цепочки
При присваивании значения унаследованному свойству создаётся собственное свойство с тем же именем - это называется shadowing. Исключение - свойства с сеттером в прототипе: тогда вызывается сеттер, а не создаётся собственное свойство.
На практике
В реальной разработке различие важно при работе с классами и наследованием. Методы обычно живут в прототипе, а данные - как собственные свойства. Это экономит память: методы не дублируются для каждого экземпляра.
При работе с фреймворками и библиотеками часто встречается паттерн проверки Object.prototype.hasOwnProperty.call(obj, key) - это защита от переопределённого hasOwnProperty на самом объекте.
Для безопасного копирования объектов с учётом только собственных свойств используют Object.entries() или Object.keys() в комбинации с Object.fromEntries().
При создании объектов через Object.create(null) объект не имеет прототипа, поэтому у него нет унаследованных свойств вообще - это полезно для словарей, где ключи могут быть __proto__ или toString.
Пример кода
JAVASCRIPTconst parent = {inherited: 'from parent',greet() {return 'Hello';}};const child = Object.create(parent);child.own = 'own property';console.log(child.inherited); // 'from parent' - унаследованноеconsole.log(child.own); // 'own property' - собственноеconsole.log(Object.keys(child)); // ['own'] - только собственныеconsole.log(child.hasOwnProperty('inherited')); // falseconsole.log(child.hasOwnProperty('own')); // trueconsole.log('inherited' in child); // true - оператор in видит цепочку// Shadowing: создаём собственное свойство с тем же именемchild.inherited = 'shadowed';console.log(child.hasOwnProperty('inherited')); // trueconsole.log(parent.inherited); // 'from parent' - прототип не изменился// Проверка через Object.getOwnPropertyNamesconsole.log(Object.getOwnPropertyNames(child)); // ['own', 'inherited']// for...in перечисляет и унаследованные перечислимые свойстваfor (const key in child) {console.log(key); // 'own', 'inherited', 'greet'}
Как отвечать на собеседовании
Начни с чёткого определения: собственные свойства - это свойства, которые принадлежат объекту напрямую, унаследованные - те, что доступны через prototype chain. Подчеркни разницу в перечислении: Object.keys() и hasOwnProperty работают только с собственными, for...in и in - с унаследованными тоже.
Покажи понимание механизма: при обращении к свойству движок сначала ищет в собственных, потом поднимается по цепочке. Упомяни shadowing - присваивание создаёт собственное свойство, перекрывающее унаследованное.
Для senior-позиции добавь нюансы: разницу в производительности доступа, поведение с сеттерами в прототипе, особенности Object.create(null), важность для сериализации и копирования. Если спросят про классы - объясни, что методы в class автоматически попадают в прототип, а поля - в собственные свойства.
Что проверяет интервьюер
Интервьюер оценивает:
- понимание prototype chain как фундаментального механизма JavaScript
- умение различать способы проверки свойств:
in,hasOwnProperty,Object.keys(),Object.getOwnPropertyNames() - знание практических следствий: сериализация, копирование, перечисление
- способность объяснить shadowing и его последствия
- для senior - понимание внутренних механизмов и edge cases
Вопрос часто служит входной точкой для более глубокого обсуждения: наследование, Object.create, классы, производительность, мемоизация через прототипы.
Типичные ошибки
- путаница между
inиhasOwnProperty- первое видит унаследованные, второе нет - утверждение, что
for...inперечисляет только собственные свойства - это неверно - игнорирование shadowing: кандидат думает, что присваивание меняет прототип - это не так
- забывают про
Object.create(null)как способ полностью исключить унаследованные свойства - не учитывают, что
JSON.stringifyсериализует только собственные перечислимые свойства - используют
obj.hasOwnProperty(key)без защиты от переопределения - правильнееObject.prototype.hasOwnProperty.call(obj, key)
> Похожие задачи по frontend
Почему parseInt в JavaScript может возвращать NaN и как влияет второй аргумент
Какие способы есть для итерации по объекту в JavaScript кроме for-in
Пример замыкания с внутренней функцией и предмет замыкания в JavaScript
Для чего нужен оператор nullish coalescing (??) и как он работает в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью