JS: Прототипы

Теория: Цепочки прототипов

Прототипы становятся действительно мощными, когда из них строят цепочки. В этом уроке разбираем, как эти цепочки устроены и как их строить правильно.

Prototype chain

Прототип моего прототипа

Для объекта, созданного через new F(), цепочка выглядит так:

  • объект -> F.prototype
  • F.prototype -> Object.prototype
  • Object.prototype -> null

Проверка:

function F() {}
const obj = new F();

const proto1 = Object.getPrototypeOf(obj);
const proto2 = Object.getPrototypeOf(proto1);

proto1 === F.prototype; // true
proto2 === Object.prototype; // true

Частая ошибка при "наследовании"

Наивный вариант:

function A() {}
function B() {}

B.prototype = A.prototype;

Проблема: это один и тот же объект. Изменения в B.prototype сразу затрагивают A.prototype.

Итог: нормальной цепочки не получается.

Правильный способ линковки

Нужен новый объект, который ссылается на A.prototype как на прототип:

function A() {}
function B() {}

B.prototype = Object.create(A.prototype);

Теперь:

  • B.prototype отдельный объект
  • его прототип - A.prototype
  • изменения в B.prototype не ломают A.prototype

Что делает Object.create

Упрощенно это можно представить так:

Object.create = function create(protoObj) {
  function F() {}
  F.prototype = protoObj;
  return new F();
};

То есть создается новый объект, уже связанный с нужным прототипом.

Почему это важно

Через корректную линковку работают:

  • прототипное наследование
  • проверка instanceof
  • общее поведение для группы объектов

new не создает "экземпляр класса" в классическом смысле. Он создает обычный объект и связывает его с prototype функции-конструктора.

Итоги

Если нужно построить иерархию прототипов, используйте Object.create, а не прямое присваивание B.prototype = A.prototype.

Это базовое правило избавляет от большого количества трудноуловимых багов.

Дальше

Завершено

0 / 10