Кратко
Object.getPrototypeOf(obj) — чтение прототипа (современный способ). Object.create(proto) — создание объекта с прототипом. __proto__ — legacy, избегайте в новом коде.
Подробно
Современные методы работы с прототипами:
- Object.getPrototypeOf(obj) — чтение:
const obj = {}; console.log(Object.getPrototypeOf(obj) === Object.prototype); // true
- Object.setPrototypeOf(obj, proto) — изменение:
const animal = { eats: true }; const rabbit = {}; Object.setPrototypeOf(rabbit, animal); console.log(rabbit.eats); // true
- Object.create(proto) — создание:
const proto = { greet() { return 'Привет'; } }; const obj = Object.create(proto); console.log(obj.greet()); // 'Привет'
__proto__ — legacy: obj.__proto__ — это геттер/сеттер для Object.getPrototypeOf/setPrototypeOf
Почему __proto__ не рекомендуется:
- Устаревший синтаксис
- Может быть не реализован в некоторых средах
- Медленнее
- Путает с prototype (свойство функции)
Правило:
- Читайте: Object.getPrototypeOf(obj)
- Изменяйте: Object.setPrototypeOf(obj, proto)
- Создавайте: Object.create(proto)
- __proto__ — только для отладки
Ментальная модель
__proto__ — как старая карта. Она работает, но есть новая навигация (Object.getPrototypeOf). Используйте новую.
Примеры
**Самый простой:**
const obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true
const arr = [];
console.log(Object.getPrototypeOf(arr) === Array.prototype); // trueObject.getPrototypeOf показывает, откуда наследуются методы.
**Простой:**
const animal = { eats: true };
// Создание с прототипом
const rabbit = Object.create(animal);
console.log(rabbit.eats); // true
console.log(Object.getPrototypeOf(rabbit) === animal); // trueObject.create — современный способ создания объекта с прототипом.
**Реальный пример:**
// Паттерн: mixin через Object.create
const Serializable = {
serialize() {
return JSON.stringify(this);
}
};
const Loggable = {
log() {
console.log(this.toString());
}
};
const user = Object.create(Serializable);
Object.assign(user, Loggable);
user.name = 'Анна';
console.log(user.serialize()); // '{"name":"Анна"}'Object.create + Object.assign — mixin паттерн.
Частые ошибки
**Неправильно:** Использовать __proto__ в продакшен-коде
**Почему:** __proto__ — legacy. Может не работать в некоторых средах.
**Правильно:** Используйте Object.getPrototypeOf и Object.create.
**Неправильно:** Путать __proto__ и prototype
**Почему:** __proto__ — свойство экземпляра (ссылка на прототип). prototype — свойство функции (чертёж).
**Правильно:** __proto__ === F.prototype для экземпляра, созданного через new F().
**Неправильно:** Использовать Object.setPrototypeOf для частых изменений
**Почему:** setPrototypeOf ломает оптимизации движка. Используйте Object.create для первоначальной настройки.
**Правильно:** setPrototypeOf — редко. Object.create — для первоначального прототипа.
Важно запомнить
- Object.getPrototypeOf(obj) — чтение прототипа
- Object.create(proto) — создание с прототипом
- Object.setPrototypeOf — изменение (осторожно!)
- __proto__ — legacy, избегайте
- __proto__ === F.prototype для экземпляра new F()
Связь
Назад: Вы знаете встроенные прототипы (JI15) — теперь у вас есть инструменты для работы с ними.
Вперёд: Следующий урок (JI17) — полный набор методов массивов.