> Какой метод вызывается при наследовании, если метод определён в прототипе родителя и в экземпляре дочернего класса в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: циан, Rutube
Стек: JavaScript
> Пример ответа
Короткий ответ
При наследовании в JavaScript, если метод определён в прототипе родителя и в экземпляре дочернего класса, вызывается метод из экземпляра дочернего класса. Это происходит из-за цепочки прототипов: сначала поиск идёт в собственном объекте, затем в прототипе родителя. Собственное свойство экземпляра "перекрывает" метод из прототипа - это называется shadowing (затенение).
Подробное объяснение
В JavaScript механизм наследования основан на цепочке прототипов. Когда вы обращаетесь к свойству или методу объекта, движок выполняет следующий алгоритм:
- Проверяет собственные свойства объекта (own properties) - те, что были созданы через
thisилиObject.defineProperty. - Если свойство не найдено, переходит к прототипу объекта (
__proto__илиObject.getPrototypeOf). - Продолжает подниматься по цепочке прототипов, пока не найдёт свойство или не достигнет
null.
В контексте классов (синтаксический сахар над прототипами):
- Методы, объявленные в теле класса, попадают в
ClassName.prototype. - Методы, объявленные в конструкторе через
this.method = ..., становятся собственными свойствами экземпляра.
При вызове child.someMethod():
- Если
someMethodопределён как собственное свойство экземпляра - вызывается он. - Если нет - поиск продолжается в
ChildClass.prototype, затем вParentClass.prototype.
Важно понимать: "переопределение" в экземпляре не изменяет прототип родителя. Оно лишь создаёт новое собственное свойство, которое "затеняет" метод из прототипа. Это поведение отличается от классического ООП, где переопределение метода в подклассе влияет на сам класс.
На практике
Этот механизм часто используется для:
- Полиморфизма - экземпляр дочернего класса может вести себя по-разному, переопределяя методы родителя.
- Декорации - вызов родительского метода через
super.method()внутри собственного метода экземпляра. - Оптимизации - иногда методы специально выносят в экземпляр, чтобы избежать лишнего прохода по цепочке прототипов (хотя это редкость).
Однако стоит помнить о trade-off: создание методов в конструкторе для каждого экземпляра увеличивает потребление памяти, так как каждая функция создаётся заново. Методы в прототипе разделяются между всеми экземплярами.
Пример кода
JAVASCRIPTclass Parent {greet() {return 'Hello from Parent';}}class Child extends Parent {constructor() {super();// Собственный метод экземпляра, затеняет метод из прототипаthis.greet = function() {return 'Hello from instance';};}}const child = new Child();console.log(child.greet()); // 'Hello from instance'// Проверка: метод в прототипе не изменилсяconsole.log(Child.prototype.greet); // undefined (метод не определён в прототипе Child)console.log(Parent.prototype.greet.call(child)); // 'Hello from Parent'// Если убрать собственное свойство - будет вызван метод из прототипаdelete child.greet;console.log(child.greet()); // 'Hello from Parent'
Как отвечать на собеседовании
Начните с прямого ответа: вызывается метод из экземпляра. Затем объясните механизм цепочки прототипов и порядок поиска. Подчеркните разницу между "переопределением" в классическом ООП и "затенением" в JavaScript. Упомяните, что это поведение одинаково для классов и функций-конструкторов. Если спросят про super - поясните, что он позволяет явно вызвать метод родителя, даже если он затенён.
Что проверяет интервьюер
Интервьюер оценивает:
- Понимание прототипного наследования, а не только синтаксиса классов.
- Знание порядка поиска свойств в цепочке прототипов.
- Умение объяснить разницу между собственными свойствами и свойствами прототипа.
- Понимание последствий для памяти и производительности.
- Способность связать теорию с практическими примерами.
Типичные ошибки
- Путаница с классическим ООП - кандидат говорит, что метод "переопределяется" в классе, хотя на самом деле создаётся новое свойство экземпляра.
- Игнорирование цепочки прототипов - ответ "вызывается метод родителя" без учёта собственных свойств.
- Непонимание
super- утверждение, чтоsuper.method()всегда вызывает метод из прототипа родителя, даже если он затенён в экземпляре (на самом делеsuperработает с прототипом, но не с собственными свойствами экземпляра). - Забывают про
delete- не упоминают, что удаление собственного свойства "открывает" доступ к методу из прототипа.
> Похожие задачи по frontend
Что такое NaN и в каких случаях он возникает
Какая конструкция может использоваться вместе с try-catch в JavaScript
Как отлавливать ошибки промисов в JavaScript
Изменяется ли исходный массив при вызове метода sort в JavaScript и почему
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью