Skip to main content

Як класи пов'язані з прототипами?

1. Клас: це просто функція

Коли ти оголошуєш клас:

javascript
class User { constructor(name) { this.name = name; } sayHi() { console.log(`Hi, ${this.name}!`); } }

JS під капотом перетворює це на щось на кшталт:

javascript
function User(name) { this.name = name; } User.prototype.sayHi = function() { console.log(`Hi, ${this.name}!`); };

Тобто class, це зручна обгортка над функцією-конструктором і її прототипом.


2. Зв'язок між класом і прототипом

Коли ти створюєш екземпляр класу:

javascript
const user = new User("Alice");

JS робить таке під капотом:

  1. Створює новий об'єкт: {}
  2. Встановлює його прототип: User.prototype
  3. Викликає конструктор: User.call(this, "Alice")

Тобто:

javascript
Object.getPrototypeOf(user) === User.prototype; // true

3. Методи класу: це властивості prototype

javascript
console.log(Object.getOwnPropertyNames(User.prototype)); // ["constructor", "sayHi"]

Кожен метод, який ти пишеш усередині class, автоматично додається в User.prototype, а не в сам об'єкт екземпляра.


4. Екземпляри мають спільний прототип

javascript
const u1 = new User("Alex"); const u2 = new User("Alice"); console.log(u1.sayHi === u2.sayHi); // true: один метод на всіх

Це і є ключова ідея прототипів: усі екземпляри розділяють спільні методи через prototype, щоб не дублювати їх у пам'яті.


5. Успадкування через extends = прототипне успадкування

javascript
class Animal { speak() { console.log("The animal makes a sound"); } } class Dog extends Animal { bark() { console.log("Woof-woof!"); } } const d = new Dog(); d.speak(); // працює

Під капотом відбувається таке:

javascript
// Пов'язує прототипи Dog.prototype.__proto__ = Animal.prototype; // Пов'язує конструктори Object.setPrototypeOf(Dog, Animal);

Тобто extends просто створює ланцюжок прототипів:

javascript
Dog.prototype → Animal.prototype → Object.prototype

6. Ланцюжок прототипів у класах

Для прикладу:

javascript
class A {} class B extends A {} const b = new B();

Ланцюжок буде таким:

javascript
b ↓ B.prototype ↓ A.prototype ↓ Object.prototype ↓ null

А для самих конструкторів:

javascript
B ↓ A ↓ Function.prototype ↓ Object.prototype ↓ null

7. Методи працюють через пошук по ланцюжку прототипів

Коли ти викликаєш b.sayHi(), рушій робить таке:

  1. Чи є sayHi в самому об'єкті b? → Ні
  2. Шукає в B.prototype → Знайшов, викликає
  3. Якщо ні, йде далі вгору по ланцюжку (A.prototype, Object.prototype...)

8. Приклад: підтвердження в коді

javascript
class Animal { move() {} } class Dog extends Animal { bark() {} } const dog = new Dog(); console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true

Усе це, це ланцюжок прототипів, створений автоматично при extends.


9. Клас: не магія, просто синтаксичний цукор

Ось еквівалент коду без class:

javascript
function Animal() {} Animal.prototype.move = function() {}; function Dog() { Animal.call(this); } Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog; Dog.prototype.bark = function() {}; const dog = new Dog(); dog.bark();

Тобто class просто робить цей код красивішим, автоматизуючи роботу з prototype і Object.create.


Підсумок

ЩоЩо клас робить під капотом
constructorФункція-конструктор
МетодиЗаписуються в Class.prototype
extendsПов'язує прототипи (Child.prototype → Parent.prototype)
super()Викликає батьківський конструктор
instanceofПеревіряє ланцюжок прототипів
ЕкземплярЗберігає дані, а методи бере з прототипу

Коротко:

Класи в JavaScript, це зручний синтаксис поверх прототипів.

Кожен клас створює:

  • функцію-конструктор,
  • об'єкт-прототип із методами,
  • і ланцюжок успадкування через __proto__.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.