Skip to main content

Ланцюжок прототипів

ланцюжок прототипів (prototype chain) - це механізм успадкування в JavaScript, через який під час звернення до властивості чи методу об'єкт шукає його не лише в себе, але й у своїх "батьків" (прототипів).


Коротко

Кожен об'єкт у JS має приховане посилання на інший об'єкт - свій прототип ([[Prototype]]), і якщо потрібна властивість не знайдена в самому об'єкті, JS шукає її в прототипі, потім у прототипі прототипу і так далі, поки не дійде до null.

Ця послідовність і називається ланцюжок прототипів.


Приклад - базовий

javascript
const animal = { eats: true }; const dog = Object.create(animal); // dog успадковує від animal dog.barks = true; console.log(dog.barks); // true (знайшов у dog) console.log(dog.eats); // true (знайшов у animal) console.log(dog.toString); // [Function: toString] (успадковано від Object.prototype)

Що відбувається:

javascript
dog -> animal -> Object.prototype -> null

JS йде по ланцюжку:

  1. Шукає barks у dog -> знайдено
  2. Шукає eats у dog -> немає -> йде в animal -> знайдено
  3. Шукає toString -> немає в animal -> йде в Object.prototype -> знайдено
  4. Далі Object.prototype.__proto__ = null -> кінець ланцюжка

Візуально

javascript
dog { barks: true } ^ animal { eats: true } ^ Object.prototype { toString(), hasOwnProperty(), ... } ^ null

Приклад з методами

javascript
const animal = { walk() { console.log('Тварина йде'); } }; const dog = Object.create(animal); dog.bark = function() { console.log('Гав!'); }; dog.walk(); // "Тварина йде" (метод знайдено у прототипу) dog.bark(); // "Гав!" (метод знайдено у dog)

JS не копіює методи, а знаходить їх під час виклику через ланцюжок.


Перевірка прототипу

javascript
console.log(Object.getPrototypeOf(dog) === animal); // true

Можна також перевірити за допомогою оператора instanceof:

javascript
console.log(dog instanceof Object); // true (тому що в ланцюжку є Object.prototype)

Приклад з класами (той самий принцип)

javascript
class Animal { eat() { console.log('Їм'); } } class Dog extends Animal { bark() { console.log('Гав'); } } const rex = new Dog(); rex.bark(); // "Гав" rex.eat(); // "Їм" (успадковано від Animal)

Під капотом це той самий механізм:

javascript
rex -> Dog.prototype -> Animal.prototype -> Object.prototype -> null

Якщо властивість знайдено - пошук зупиняється

javascript
const animal = { eats: true }; const dog = Object.create(animal); dog.eats = false; console.log(dog.eats); // false (знайшов у самому dog, далі не шукає)

JS завжди використовує першу знайдену властивість у ланцюжку.


Можна змінити прототип вручну (але небажано)

javascript
const cat = { meow: true }; Object.setPrototypeOf(dog, cat); console.log(dog.meow); // true

Так можна перебудувати ланцюжок, але це повільно і зазвичай не рекомендується робити в продакшені.


Підсумок

ЕтапЩо відбувається
1JS шукає властивість у самому об'єкті
2Якщо немає - йде у прототип ([[Prototype]])
3Потім - у прототип прототипу
4І так далі, поки не дійде до null
Якщо не знайдено нідеПовертає undefined

Приклад підсумкової схеми

javascript
rex -> Dog.prototype -> Animal.prototype -> Object.prototype -> null
РівеньДе зберігаєтьсяПриклад
rexвласні властивостіrex.name = 'Rex'
Dog.prototypeметоди класу Dogbark()
Animal.prototypeметоди базового класуeat()
Object.prototypeстандартні методиtoString(), hasOwnProperty()

В одній фразі:

Ланцюжок прототипів - це шлях, яким JavaScript шукає властивості й методи, переходячи від об'єкта до його прототипу, поки не знайде потрібне або не дійде до null.

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

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

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