Кратко
Каждая функция имеет свойство prototype. Когда вы создаёте объект через new, его [[Prototype]] ссылается на constructor.prototype. Это связывает экземпляр с классом/конструктором.
Подробно
Что делает new?
new User('Анна') делает 4 вещи:
- Создаёт новый пустой объект {}
- Устанавливает его [[Prototype]] = User.prototype
- Вызывает User.call(this, 'Анна') — constructor
- Возвращает объект (если constructor не возвращает другой)
Связь: User.prototype === user.__proto__
Это значит:
- Методы, определённые в User.prototype, доступны экземпляру
- Изменение User.prototype влияет на все экземпляры
F.prototype vs Object.getPrototypeOf:
- F.prototype — свойство функции (для нового экземпляра)
- Object.getPrototypeOf(obj) — текущий прототип объекта
Важно:
- F.prototype = {} — замена прототипа (осторожно!)
- Object.create(proto) — создание с прототипом
Ментальная модель
F.prototype — как чертёж. new User() берёт чертёж User.prototype и создаёт дом. Все дома (экземпляры) используют один чертёж. Важно: это не копирование чертежа в каждый объект — объекты используют общий прототип для поиска свойств и методов.
Примеры
**Самый простой:**
function User(name) {
this.name = name;
}
User.prototype.greet = function() {
return `Привет, ${this.name}`;
};
const user = new User('Анна');
console.log(user.greet()); // 'Привет, Анна'
console.log(user.__proto__ === User.prototype); // trueUser.prototype становится прототипом экземпляра.
**Простой:**
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return `${this.name} издаёт звук`;
};
function Dog(name, breed) {
Animal.call(this, name); // вызов родителя
this.breed = breed;
}
// Наследование прототипа
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
return `${this.name} гавкает`;
};
const rex = new Dog('Рекс', 'овчарка');
console.log(rex.speak()); // 'Рекс гавкает'Прототипное наследование через Object.create.
**Реальный пример:**
// class = синтаксический сахар:
// class User { greet() {} }
// эквивалентно:
// function User(name) { this.name = name; }
// User.prototype.greet = function() {};
// Доказательство:
class User {
constructor(name) { this.name = name; }
greet() { return `Привет, ${this.name}`; }
}
const user = new User('Анна');
console.log(typeof User); // 'function'
console.log(User.prototype.greet); // function
console.log(user.__proto__ === User.prototype); // trueclass — это function + prototype под капотом.
Частые ошибки
**Неправильно:** Забывать Dog.prototype.constructor = Dog
**Почему:** После Object.create() constructor ссылается на Animal, а не Dog.
**Правильно:** Восстанавливайте constructor: Dog.prototype.constructor = Dog.
**Неправильно:** Путать F.prototype и Object.getPrototypeOf
**Почему:** F.prototype — для нового экземпляра. getPrototypeOf — текущий прототип.
**Правильно:** F.prototype используется new. Object.getPrototypeOf — для чтения.
**Неправильно:** Менять F.prototype после создания экземпляров
**Почему:** Экземпляры уже ссылаются на старый prototype. Новые методы не будут доступны.
**Правильно:** Определяйте prototype ДО создания экземпляров.
Важно запомнить
- new создаёт объект с [[Prototype]] = F.prototype
- F.prototype — «чертёж» для экземпляров
- Object.getPrototypeOf() — чтение текущего прототипа
- class = function + prototype (синтаксический сахар)
- Восстанавливайте constructor после Object.create()
Связь
Назад: Вы знаете цепочку прототипов (JI13) — теперь вы видите, как конструкторы с ней связаны.
Вперёд: Следующий урок (JI15) — встроенные прототипы: Array.prototype, Object.prototype.