Кратко
Каждый объект имеет [[Prototype]] — ссылку на другой объект. Когда вы обращаетесь к свойству, JavaScript ищет его в объекте, потом в его прототипе, потом в прототипе прототипа... пока не найдёт или не дойдёт до null.
Подробно
Что такое прототип?
У каждого объекта есть скрытое свойство [[Prototype]] — ссылка на другой объект (прототип).
Когда JavaScript ищет свойство:
- Ищет в самом объекте
- Если не нашёл — идёт в [[Prototype]]
- Там тоже ищет
- И так далее по цепочке
- Если дошёл до null — возвращает undefined
Цепочка прототипов (Prototype Chain): obj → obj.__proto__ → obj.__proto__.__proto__ → ... → Object.prototype → null
Пример: const arr = [1, 2, 3]; arr.map(...); // map не в самом arr — он в Array.prototype! arr.toString(); // toString в Object.prototype!
Определение прототипа:
- Object.create(proto) — создаёт объект с указанным прототипом
- __proto__ (legacy) — чтение/запись прототипа
- Object.getPrototypeOf(obj) — современный способ чтения
Важно: prototype — это свойство ФУНКЦИИ (класса), [[Prototype]] — это свойство ОБЪЕКТА.
Ментальная модель
Prototype chain — как семья. Если вы ищете «деньги» и у вас нет — вы идёте к родителям. Если у родителей нет — к дедушке. И так далее, пока не найдёте или не дойдёте до null.
Примеры
**Самый простой:**
const animal = { eats: true };
const rabbit = Object.create(animal);
console.log(rabbit.eats); // true (из прототипа!)
console.log(rabbit.jumps); // undefined
console.log(Object.getPrototypeOf(rabbit) === animal); // trueObject.create создаёт объект с указанным прототипом.
**Простой:**
const arr = [1, 2, 3];
// map определён в Array.prototype
console.log(arr.map(x => x * 2)); // [2, 4, 6]
// toString определён в Object.prototype
console.log(arr.toString()); // '1,2,3'
// Цепочка: arr → Array.prototype → Object.prototype → nullМетоды массивов — из Array.prototype. Методы объектов — из Object.prototype.
**Реальный пример:**
const userMethods = {
greet() {
return `Привет, ${this.name}`;
},
toString() {
return `User(${this.name})`;
}
};
const user1 = Object.create(userMethods);
user1.name = 'Анна';
const user2 = Object.create(userMethods);
user2.name = 'Пётр';
console.log(user1.greet()); // 'Привет, Анна'
console.log(user2.greet()); // 'Привет, Пётр'
// Один прототип — много объектовПрототип как шаблон для методов.
Частые ошибки
**Неправильно:** Путать prototype и [[Prototype]]
**Почему:** prototype — свойство функции. [[Prototype]] — свойство объекта. Разные вещи!
**Правильно:** Function.prototype — для функций. Object.getPrototypeOf(obj) — для объектов.
**Неправильно:** Использовать __proto__ как основной способ
**Почему:** __proto__ — legacy. Используйте Object.getPrototypeOf() и Object.create().
**Правильно:** Object.getPrototypeOf(obj) — современный способ.
**Неправильно:** Думать, что prototype chain — это копирование
**Почему:** Это ССЫЛКА, не копия. Изменение прототипа влияет на все объекты.
**Правильно:** Prototype — ссылка, не копия.
Важно запомнить
- Каждый объект имеет [[Prototype]]
- Свойства ищутся по цепочке прототипов
- prototype — свойство функции, [[Prototype]] — свойство объекта
- Object.create(proto) — современное создание с прототипом
- Цепочка: obj → proto → ... → Object.prototype → null
Связь
Назад: Вы знаете instanceof (JI12) — теперь вы понимаете, как он устроен внутри.
Вперёд: Следующий урок (JI14) — F.prototype и функции-конструкторы.