Как работает наследование в JavaScript с использованием super и методов родительского класса?
Что проверяют
Понимаете ли вы, что class и extends это синтаксис поверх прототипов, и как именно super находит метод родителя. Следом обычно спрашивают, что будет без вызова super() в конструкторе, или просят переписать пример на прототипах.
Как отвечать
class Dog extends Animal создаёт две связи: Dog.prototype наследует от Animal.prototype (методы экземпляров), а сам Dog наследует от Animal (статические методы). Метод ищется по цепочке: сам объект, Dog.prototype, Animal.prototype, Object.prototype.
У super три варианта использования:
super(...args)в конструкторе: вызывает конструктор родителя, и именно он создаёт объект. До этого вызоваthisв наследнике недоступен, обращение к нему броситReferenceError;super.method()в методе: вызывает метод родителя с текущимthis. Так переопределённый метод дополняет родительский, а не дублирует его код;superвstatic-методе: обращается к статическим методам родителя.
Если конструктор в наследнике не объявлен, подставляется конструктор по умолчанию, который вызывает super(...args). Пустой конструктор ради одной строки с super писать не нужно.
Тонкость, которая выделяет ответ: super привязан не к this, а к объекту, где метод объявлен (внутреннее поле [[HomeObject]]). Поэтому метод, скопированный в другой объект, продолжит обращаться к прежнему родителю.
Из фронтенда хороший пример: веб-компоненты, где класс наследует HTMLElement, а constructor обязан начинаться с super(). Там же уместно сказать, что в React компоненты строят композицией, а не наследованием.
Где спотыкаются
Обращаются к this до super() и не могут объяснить, почему код падает. Причина в том, что объект создаёт конструктор родителя, до его вызова this не инициализирован.
Считают, что классы в JavaScript работают как в Java и копируют методы в наследника. Методы остаются на прототипе родителя и находятся поиском по цепочке.
Передают метод как колбэк без привязки и удивляются: super.method() находится, а this.name внутри падает. super определяется местом объявления метода, а this способом вызова.