Как работает прототипное наследование в JavaScript?
Что проверяют
Понимаете ли вы, что наследование здесь идёт по цепочке объектов, а class это синтаксис поверх того же механизма.
Как отвечать
У каждого объекта есть скрытая ссылка на другой объект, его прототип. Не нашли свойство у объекта, ищем у прототипа, потом у прототипа прототипа, и так до null. Это и есть цепочка прототипов.
const animal = { speak() { return "звук"; } };
const dog = Object.create(animal);
dog.speak(); // нашлось у прототипа
Object.getPrototypeOf(dog); // animalФункции-конструкторы связаны с этим через свойство prototype: new Foo() создаёт объект, прототипом которого становится Foo.prototype. Методы кладут туда, а не в конструктор, чтобы не копировать их в каждый экземпляр.
class это тот же механизм в удобной записи: extends выстраивает цепочку, super вызывает метод прототипа. Классы не превращают JavaScript в язык с классами в классическом смысле.
Важные детали: запись всегда идёт в сам объект, а не в прототип, поэтому присваивание не меняет общий метод. hasOwnProperty отличает своё свойство от унаследованного. __proto__ устарел, используются Object.getPrototypeOf и Object.setPrototypeOf, причём менять прототип существующему объекту дорого.
Где спотыкаются
Путают prototype у функции и __proto__ у объекта.
Считают, что class завёл настоящее классовое наследование.
Кладут методы прямо в конструктор и получают отдельную копию функции на каждый объект.
Перебирают объект через for...in, забывая, что он идёт и по унаследованным свойствам.