> Какой метод вызывается при наследовании, если метод определён в прототипе родителя и в экземпляре дочернего класса в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: НордКлан
Стек: JavaScript
> Пример ответа
Короткий ответ
При наследовании, если метод определён в прототипе родителя и в экземпляре дочернего класса, вызывается метод из экземпляра. JavaScript сначала ищет свойство в самом объекте, и только если его там нет - поднимается по цепочке прототипов. Это называется shadowing: собственное свойство экземпляра "затеняет" метод прототипа.
Подробное объяснение
Механизм разрешения свойств в JavaScript основан на цепочке прототипов. Когда вы обращаетесь к child.method(), движок выполняет следующие шаги:
- Проверяет собственные свойства объекта
child(own properties). Если метод найден - вызывается он. - Если не найден - переходит к
Object.getPrototypeOf(child), то есть кChild.prototype. - Если и там нет - продолжает подниматься по цепочке до
Object.prototypeи далее доnull.
Важно понимать: при использовании class и extends методы, объявленные в теле класса, попадают в Child.prototype, а не в экземпляр. Но если вы присваиваете метод напрямую экземпляру (this.method = ... или child.method = ...), он становится собственным свойством и имеет приоритет.
Это поведение одинаково для ES6 классов и для классического прототипного наследования через Object.create или функции-конструкторы. Ключевой момент - порядок поиска: собственное свойство всегда выигрывает.
На практике
В реальной разработке этот механизм часто используется для переопределения поведения в конкретном экземпляре, не затрагивая другие экземпляры и сам класс. Например, для временной модификации метода в тестах или для реализации стратегий.
Однако стоит помнить о производительности: собственные свойства экземпляра замедляют доступ по сравнению с методами прототипа, так как движок должен проверять наличие собственного свойства перед переходом к прототипу. Для горячих путей лучше избегать shadowing.
Также важно не путать shadowing с переопределением метода в подклассе. Когда вы объявляете метод с тем же именем в class Child extends Parent, вы переопределяете его на уровне Child.prototype - это тоже shadowing, но на уровне прототипа, а не экземпляра.
Пример кода
JAVASCRIPTclass Parent {greet() {return 'Привет от родителя';}}class Child extends Parent {}const child = new Child();console.log(child.greet()); // 'Привет от родителя' - метод из Parent.prototype// Добавляем собственный метод экземпляруchild.greet = function() {return 'Привет от конкретного экземпляра';};console.log(child.greet()); // 'Привет от конкретного экземпляра' - собственное свойствоconst anotherChild = new Child();console.log(anotherChild.greet()); // 'Привет от родителя' - не затронут// Проверка цепочкиconsole.log(child.hasOwnProperty('greet')); // trueconsole.log(anotherChild.hasOwnProperty('greet')); // false
Как отвечать на собеседовании
Начните с прямого ответа: вызывается метод из экземпляра. Затем кратко объясните механизм цепочки прототипов: сначала собственные свойства, потом прототип. Упомяните термин shadowing. Если интервьюер попросит углубиться - расскажите про разницу между переопределением в подклассе и присваиванием экземпляру, приведите пример. Хорошо показать понимание, что class - это синтаксический сахар над прототипами.
Для уровня senior стоит добавить нюанс: собственные свойства экземпляра создают "скрытый класс" (hidden class) в V8, что может привести к деоптимизации. Это покажет глубокое понимание внутренностей движка.
Что проверяет интервьюер
Интервьюер оценивает:
- понимание модели наследования в JavaScript, а не просто знание синтаксиса
class; - умение объяснить механизм разрешения свойств через цепочку прототипов;
- знание термина shadowing и его последствий;
- способность отличить переопределение метода в подклассе от присваивания экземпляру;
- для senior - понимание влияния на производительность и внутренние механизмы движков.
Типичные ошибки
- Утверждение, что вызывается метод родителя - это неверно, если есть собственное свойство экземпляра.
- Путаница между
Child.prototype.methodиchild.method- это разные уровни цепочки. - Забывают, что методы класса не попадают в экземпляр автоматически, они живут в прототипе.
- Думают, что
superкак-то влияет на разрешение - нет,superработает только внутри методов класса и не меняет порядок поиска для обычных вызовов. - Не учитывают, что присваивание метода экземпляру после создания объекта работает точно так же, как если бы метод был определён в конструкторе через
this.method = ....
> Похожие задачи по frontend
Как сборщик мусора находит неиспользуемые объекты в JavaScript
Почему для обработки промисов используют конструкции вместо console.log напрямую
В чем разница между статическими и нестатическими методами в классах JavaScript
Как проверять разные наборы полей одного класса при десериализации JSON в тестах
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью