Краткий ответ: __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);
Такой объект является лучшей картой (словарем), чем литеральный объект, поэтому этот шаблон иногда называют шаблоном dict (dict для словаря).
Примечание: литеральные объекты, созданные с использованием {}
, являются экземплярами Object
, поскольку ({}).__proto__
является ссылкой на Object.prototype
.
person
explogx
schedule
29.05.2020
newtoy.prototype
не равноnewtoy.constructor.prototype
и, следовательно,newtoy.constructor.prototype
не будет иметь свойства с именемrating
. Точно так жеnewtoy.constructor.prototype.constructor.property
также не будет иметь свойства с именемrating
. - person bits   schedule 09.10.2012newtoy.constructor.prototype
будет иметь свойство, называемое рейтингом. Точно так жеnewtoy.constructor.prototype.constructor.property
также будет иметь свойство, называемое рейтингом. - person bits   schedule 20.03.2013__proto__
Против.prototype
в JavaScript и Как работает JavaScript.prototype
? - person Bergi   schedule 15.03.2014