Краткий ответ: __proto__
ссылка на prototype
свойство конструктора, который создал объект.
Объекты в JavaScript
Объект JavaScript - это встроенный тип для набора нулевых или более свойств. Свойства - это контейнеры, которые содержат другие объекты, примитивные значения или функции.
Конструкторы в JavaScript
Функции - это обычные объекты (которые реализуются [[Call]]
в терминах ECMA-262) с дополнительной возможностью вызова, но они играют другую роль в JavaScript: они становятся конструкторами ( фабриками для объектов), если вызываются через new
оператор. Таким образом, конструкторы являются грубым аналогом классов в других языках.
Каждая функция JavaScript на самом деле является экземпляром объекта Function
встроенной функции, который имеет специальное имя, prototype
используемое для реализации наследования на основе прототипа и общих свойств. Каждый объект, созданный функцией конструктора, имеет неявную ссылку (называемую прототипом или __proto__
) на значение своего конструктора prototype
.
Конструктор prototype
является своего рода планом построения объектов, поскольку каждый объект, созданный конструктором, наследует ссылку на свой объект prototype
.
Прототип цепи
Объект указывает свой прототип через внутреннее свойство [[Prototype]]
или __proto__
. Отношения прототипа между двумя объектами связаны с наследованием: каждый объект может иметь другой объект в качестве своего прототипа. Прототип может быть null
ценным.
Цепочка объектов, связанных __proto__
свойством, называется цепочкой прототипов . Когда делается ссылка на свойство в объекте, это ссылка на свойство, обнаруженное в первом объекте в цепочке прототипов, который содержит свойство с таким именем. Прототип цепочки ведет себя так, как если бы это был один объект.
Смотрите это изображение (извлечено из этого блога ):
Всякий раз, когда вы пытаетесь получить доступ к свойству объекта, JavaScript начинает его поиск в этом объекте и продолжает его прототип, прототип прототипа и т. Д. До тех пор, пока свойство не будет найдено или если оно не будет __proto__
содержать значение null
.
Этот тип наследования с использованием цепочки прототипов часто называют делегированием, чтобы избежать путаницы с другими языками, использующими цепочку классов.
Почти все объекты являются экземплярами Object
, потому что Object.prototype
последний в их цепочке прототипов. Но Object.prototype
это не случай, Object
потому что Object.prototype.__proto__
имеет значение null
.
Вы также можете создать объект с null
прототипом, например так:
var dict = Object.create(null);
Такой объект является лучше картой (словарь) , чем буквальный объект, поэтому этот образец иногда называют ДИКТ паттерном ( ДИКТ для словаря).
Примечание. Литеральные объекты, созданные с использованием, {}
являются экземплярами, Object
поскольку ({}).__proto__
ссылка является ссылкой на Object.prototype
.