Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працює прототипне успадкування і що роблять класи під капотом?

Кожен об'єкт має приховане посилання на інший об'єкт - прототип (Object.getPrototypeOf(obj)). Якщо властивості немає в самому об'єкті, рушій шукає її в прототипі, потім у прототипі прототипу - і так до null. Це ланцюжок прототипів.

const animal = { speak() { return `${this.name} подає голос`; } };
const dog = Object.create(animal);
dog.name = 'Рекс';
dog.speak(); // знайдено в прототипі; this - dog

Класи - синтаксис над тим самим механізмом:

class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name} подає голос`; }
}

class Dog extends Animal {
  speak() { return `${super.speak()}: гав`; }
}

Під капотом Animal - функція-конструктор, методи лежать в Animal.prototype, а extends будує ланцюжок Dog.prototype → Animal.prototype → Object.prototype. Методи не копіюються в кожен екземпляр - усі екземпляри ділять одні й ті самі методи через прототип.

Що відрізняє класи від «ручних» конструкторів:

  • клас не можна викликати без new;
  • тіло класу завжди в строгому режимі;
  • приватні поля #secret - справді приватні, на рівні мови, а не за домовленістю;
  • поля класу (count = 0) створюються на кожному екземплярі, а не в прототипі.

Пастки:

  • Змінюваний об'єкт у прототипі спільний для всіх екземплярів: масив, доданий у прототип, - один на всіх.
  • Розширювати вбудовані прототипи (Array.prototype.myMethod = ...) погано: конфлікти з бібліотеками й майбутніми версіями мови.

Докладніше в документації: Успадкування і ланцюжок прототипів

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання