Що таке прототип?
Прототип (prototype) - це механізм наслідування в JavaScript, через який одні об'єкти можуть наслідувати властивості і методи інших об'єктів.
Це основа прототипного наслідування, на якому побудований весь об'єктно-орієнтований JS.
Коротко
Кожен об'єкт у JavaScript має приховане посилання на інший об'єкт - це і є його прототип.
Це посилання зберігається у спеціальній внутрішній властивості:
[[Prototype]](доступна через __proto__ або Object.getPrototypeOf())
Приклад
const user = {
sayHi() {
console.log('Привіт!');
}
};
const admin = Object.create(user); // створюємо об'єкт, що наслідує від user
admin.sayHi(); // "Привіт!"Тут:
adminне має власного методуsayHi;- але при зверненні
admin.sayHi()JS шукає цей метод у прототипі (user).
Як працює ланцюжок прототипів
Коли ти звертаєшся до obj.prop, рушій JS робить таке:
- Шукає
propу самому об'єктіobj. - Якщо не знаходить - шукає в
obj.[[Prototype]]. - Якщо там теж немає - йде далі вгору по ланцюжку прототипів.
- Якщо доходить до
null-> повертаєundefined.
Це називається ланцюжок прототипів (prototype chain).
Приклад з ланцюжком
const animal = { eats: true };
const dog = Object.create(animal);
dog.barks = true;
console.log(dog.barks); // true (у власному об'єкті)
console.log(dog.eats); // true (успадковано від animal)
console.log(dog.toString); // [Function: toString] (успадковано від Object)dog -> animal -> Object.prototype -> null
Це ланцюжок прототипів.
Перевіримо, хто чий прототип
console.log(Object.getPrototypeOf(dog) === animal); // true
console.log(Object.getPrototypeOf(animal) === Object.prototype); // trueПрототип і функції-конструктори
Коли ти створюєш об'єкт через new,
його прототипом стає властивість .prototype функції-конструктора:
function User(name) {
this.name = name;
}
User.prototype.sayHi = function() {
console.log(`Привіт, ${this.name}`);
};
const tim = new User('Tim');
tim.sayHi(); // "Привіт, Tim"Під капотом:
new User()створює новий об'єкт;- цей об'єкт отримує
[[Prototype]] = User.prototype.
Перевіримо
console.log(Object.getPrototypeOf(tim) === User.prototype); // trueПриклад: вбудовані прототипи
Майже все в JS засноване на прототипах
const arr = [1, 2, 3];
console.log(Object.getPrototypeOf(arr) === Array.prototype); // true
console.log(Object.getPrototypeOf(Array.prototype) === Object.prototype); // trueТобто:
arr → Array.prototype → Object.prototype → nullСучасний аналог - class
Синтаксис class у JavaScript - це просто "цукор" над прототипами:
class User {
sayHi() {
console.log('Привіт!');
}
}
const tim = new User();
tim.sayHi(); // "Привіт!"Під капотом class робить те саме:
створює функцію і встановлює прототипи через User.prototype.
Підсумок
| Термін | Опис |
|---|---|
| Прототип | Об'єкт, від якого інший об'єкт наслідує властивості |
| [[Prototype]] | Внутрішнє посилання на цей об'єкт |
| Ланцюжок прототипів | Послідовний пошук властивості вгору по ланцюжку |
| Object.getPrototypeOf(obj) | Отримати прототип об'єкта |
| Object.setPrototypeOf(obj, proto) | Змінити прототип |
| Object.create(proto) | Створити об'єкт із вказаним прототипом |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.