Кратко
Прототипное наследование — каждый объект имеет ссылку [[Prototype]]. Object.create(proto) создаёт объект с явным прототипом. Prototype chain — цепочка поиска свойств: свойство → [[Prototype]] → [[Prototype]] → ... → null. Делегирование — когда методы определены на прототипе, а не на каждом экземпляре.
Подробно
Object.create(proto):
const parent = { greet() { return Hello, ${this.name}; } };
const child = Object.create(parent);
child.name = 'Анна';
console.log(child.greet()); // 'Hello, Анна'
child.greet не определён → поиск в parent → найден.
Prototype chain: child → parent → Object.prototype → null
Проверка цепочки: console.log(Object.getPrototypeOf(child) === parent); // true console.log(Object.getPrototypeOf(parent) === Object.prototype); // true console.log(Object.getPrototypeOf(Object.prototype) === null); // true
Делегирование (vs наследование): // Наследование: child НАСЛЕДУЕТ от parent // Делегирование: child ДЕЛЕГИРУЕТ родителю
const vehicle = { start() { console.log('Engine started'); }, stop() { console.log('Engine stopped'); } };
const car = Object.create(vehicle); car.drive = function() { console.log('Driving'); }; // car.start() → не найдено → delegation → vehicle.start()
Конструктор и prototype:
function User(name) {
this.name = name;
}
User.prototype.greet = function() {
return Hi, ${this.name};
};
const user = new User('Анна'); // user → User.prototype → Object.prototype → null
Ментальная модель
Prototype chain — как цепочка рекомендаций. Вы спрашиваете: «Кто знает greet?» → «Я не знаю, но мой prototype знает» → «Я тоже не знаю, но мой prototype знает» → ... → «Никто не знает» (null). Object.create — как создать нового сотрудника с указанием его наставника.
Примеры
**Самый простой:**
const parent = { type: 'parent' };
const child = Object.create(parent);
console.log(child.type); // 'parent' (из прототипа)
console.log('type' in child); // true
console.log(child.hasOwnProperty('type')); // false
// type принадлежит parent, не childПоиск свойств через prototype chain.
**Простой:**
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return `${this.name} makes a sound`;
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
return `${this.name} barks`;
};
const rex = new Dog('Rex');
console.log(rex.speak()); // 'Rex makes a sound'
console.log(rex.bark()); // 'Rex barks'Ручное наследование через прототипы.
**Реальный пример:**
// Делегирование для событий
const eventBus = {
listeners: {},
on(event, fn) {
(this.listeners[event] = this.listeners[event] || []).push(fn);
},
emit(event, data) {
(this.listeners[event] || []).forEach(fn => fn(data));
}
};
const userEvents = Object.create(eventBus);
userEvents.on('login', (user) => console.log(`${user} logged in`));
userEvents.emit('login', 'Анна'); // 'Анна logged in'
// Делегирование: userEvents не определяет on/emit, но получает их от eventBusДелегирование через Object.create для event bus.
Частые ошибки
**Неправильно:** Путать prototype и [[Prototype]]
**Почему:** prototype — свойство функции (constructor.prototype). [[Prototype]] — внутренняя ссылка объекта.
**Правильно:** prototype — у функции-конструктора. [[Prototype]] — у каждого объекта.
**Неправильно:** Думать, что наследование и делегирование — одно и то же
**Почему:** Наследование: child получает свойства parent. Делегирование: child ссылается на parent для поиска.
**Правильно:** Наследование = копирование. Делегирование = ссылка.
**Неправильно:** Забывать Object.create для delegation
**Почему:** Без Object.createprototype chain может быть нарушена ( например: Child.prototype = new Parent()).
**Правильно:** Используйте Object.create для явного создания цепочки.
Важно запомнить
- Object.create(proto) — создание с прототипом
- Prototype chain: object → parent → Object.prototype → null
- Делегирование ≠ наследование
- hasOwnProperty проверяет own properties
- Конструктор + prototype = традиционное наследование
Связь
Назад: Вы знаете прототипы (JI13–JI16). Этот урок глубже разбирает внутреннее устройство цепочки и делегирование.
Вперёд: Следующий урок (JV7) — Proxy и Reflect — перехват операций над объектами.