JS Intermediate

Прототипное наследование

Понять, как JavaScript ищет свойства через цепочку прототипов (prototype chain), и чем это отличается от классического наследования.

Средний (Intermediate)
Нужно знать:КлассыОбъекты

Кратко

Каждый объект имеет [[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.


Примеры

**Самый простой:**

javascript
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); // true

Object.create создаёт объект с указанным прототипом.

**Простой:**

javascript
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.

**Реальный пример:**

javascript
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 и функции-конструкторы.


Читайте дальше

Материалы курса JS Intermediate — PROlab Academy.