function Gadget(name, color)
{
this.name = name;
this.color = color;
}
Gadget.prototype.rating = 3
var newtoy = new Gadget("webcam", "black")
newtoy.constructor.prototype.constructor.prototype.constructor.prototype
Всегда возвращает объект с рейтингом = 3.
Но если я сделаю следующее:
newtoy.__proto__.__proto__.__proto__
Цепочка заканчивается возвращением null
.
Также в Internet Explorer, как я могу проверить нулевое значение, если нет __proto__
свойства?
javascript
inheritance
prototype-programming
xdevel2000
источник
источник
newtoy.prototype
она не равнаnewtoy.constructor.prototype
и, следовательноnewtoy.constructor.prototype
, не будет вызываться свойствоrating
. Точно такnewtoy.constructor.prototype.constructor.property
же не будет называться свойствоrating
.newtoy.constructor.prototype
будет иметь свойство под названием рейтинг. Точно так жеnewtoy.constructor.prototype.constructor.property
будет иметь свойство под названием рейтинг.__proto__
Vs.prototype
в JavaScript и как работает JavaScript.prototype
?Ответы:
Я пытался обернуть это вокруг себя недавно и наконец придумал эту «карту», которая, я думаю, проливает полный свет на этот вопрос
http://i.stack.imgur.com/KFzI3.png
Я знаю, что я не первый, кто придумывает это, но было интереснее выяснить это, чем найти это :-). Во всяком случае, после этого я нашел, например, еще одну диаграмму, которая, я думаю, говорит в основном то же самое:
Макет объекта Javascript
Самым удивительным для меня было обнаружение того, на что
Object.__proto__
указываетFunction.prototype
вместоObject.prototype
, но я уверен, что для этого есть веская причина :-)Я вставляю код, упомянутый на картинке, а также, если кто-то хочет его протестировать. Обратите внимание, что некоторые свойства добавлены к объектам, чтобы было легче узнать, где мы находимся после нескольких прыжков:
источник
Object.__proto__
указывается на это,Function.prototype
заключается в том, чтоObject()
сама по себе является нативной функцией, которая создает пустой объект. Следовательно,Object()
это функция. Вы обнаружите, что__proto__
свойства всех других основных нативных типов указывают наFunction.prototype
.Object
,Function
,String
,Number
, ИArray
все унаследуют функциональный прототип.Object
сам по себе является функцией; результат выполнения вызываемогоObject
(то есть возвращаемого значения выполненияObject()
) не является функцией.constructor
является предопределенным свойством [[DontEnum]] объекта, на который указываетprototype
свойство объекта функции, и первоначально будет указывать на сам объект функции.__proto__
эквивалентно внутреннему свойству [[Prototype]] объекта, то есть его фактическому прототипу.Когда вы создаете объект с
new
оператором, его внутреннее свойство [[Prototype]] будет установлено на объект, на который указываетprototype
свойство функции конструктора .Это означает, что
.constructor
будет вычисляться.__proto__.constructor
, т.е. функция конструктора, используемая для создания объекта, и, как мы узнали,protoype
свойство этой функции использовалось для установки объекта [[Prototype]].Отсюда следует, что
.constructor.prototype.constructor
это идентично.constructor
(до тех пор, пока эти свойства не были перезаписаны); смотрите здесь для более подробного объяснения.Если
__proto__
доступно, вы можете пройтись по фактической цепочке прототипов объекта. Нет простого способа сделать это в простом ECMAScript3, потому что JavaScript не был разработан для иерархий с глубоким наследованием.источник
.constructor.prototype
цепочкой. Мне также было неясно для меня, хотя я не видел, что.constructor
равно.__proto__.constructor
. Это просто означает циклический переход между функцией конструктора и ее прототипом.Prototypal Inheritance в JavaScript основан на
__proto__
свойстве в том смысле, что каждый объект наследует содержимое объекта, на которое ссылается его__proto__
свойство.prototype
Свойство является особенным только дляFunction
объектов , и только при использованииnew
оператора называть вFunction
качестве конструктора. В этом случае созданный объект__proto__
будет установлен на конструкторFunction.prototype
.Это означает, что добавление к
Function.prototype
автоматически отразится на всех объектах,__proto__
на которые ссылаетсяFunction.prototype
.Замена конструктора
Function.prototype
другим объектом не приведет к обновлению__proto__
свойства ни для одного из уже существующих объектов.Обратите внимание, что
__proto__
свойство не должно быть доступно напрямую, вместо него следует использовать Object.getPrototypeOf (object) .Чтобы ответить на первый вопрос, я создал специальную диаграмму
__proto__
иprototype
ссылки, к сожалению, stackoverflow не позволяет мне добавлять изображение с «репутацией менее 10». Может быть, в другой раз.[Edit] Рисунок использует
[[Prototype]]
вместо того,__proto__
потому что именно так спецификация ECMAScript ссылается на внутренние объекты. Я надеюсь, что вы можете понять все.Вот несколько советов, которые помогут вам понять фигуру:
Обратите внимание, что
constructor
свойство не существует в созданных объектах, но наследуется от прототипа.источник
new MyFunction()
создает экземпляр объекта, который__proto__
должен ссылаться на его прототип ctor.MyFunction.prototype.
Так почему жеMyFunction.prototype.__proto__
ссылка на негоObject.prototype
? он должен ссылаться (как мой первый образец) на прототип своего ctor, который являетсяMyFunction.prototype
(обратите внимание, чтоMyFunction.prototype
это примерMyfunction
)Object
Ева, аFunction
Адам, Адам (Function
) использует свою кость (Function.prototype
) для создания Евы (Object
). Тогда кто создал Адама (Function
)? - Изобретатель языка JavaScript :-).Согласно ответу Усаины, я хочу добавить больше полезной информации.
Так не должно быть.
Object.__proto__
НЕ должен указывать наObject.prototype
. Вместо этого, экземплярObject
o
,o.__proto__
должен указывать наObject.prototype
.(Простите за использование терминов
class
иinstance
в JavaScript, но вы это знаете :-)Я думаю, что
Object
сам класс является примеромFunction
, вот почемуObject.__proto__ === Function.prototype
. Следовательно:Object
Ева иFunction
Адам, Адам (Function
) использует свою кость (Function.prototype
) для создания Евы (Object
).Кроме того, даже сам класс
Function
является экземпляром самогоFunction
себя, то естьFunction.__proto__ === Function.prototype
поэтомуFunction === Function.constructor
Более того, регулярный класс
Cat
является экземпляромFunction
, то естьCat.__proto__ === Function.prototype
.Причина вышеизложенного заключается в том, что когда мы создаем класс в JavaScript, фактически мы просто создаем функцию, экземпляром которой должен быть
Function
.Object
иFunction
являются просто особенными, но они все еще являются классами, в то времяCat
как это обычный класс.Фактически, в движке Google Chrome JavaScript, следующие 4:
Function.prototype
Function.__proto__
Object.__proto__
Cat.__proto__
Они все
===
(абсолютно равны) другим 3, и их значениеfunction Empty() {}
ХОРОШО. Тогда кто создает специальные
function Empty() {}
(Function.prototype
)? Подумай об этом :-)источник
function Empty() {}
вы называете равным Function.prototype и т. Д., Какой код вы использовали в консоли chrome?function Empty() {}
в Google Chrome. Я также добавил консольный вывод._ _proto_ _
) от Function.prototype. Это так просто :)Я действительно не знаю, почему люди не исправили вас о том, где на самом деле проблема в вашем понимании.
Это облегчит вам задачу
Итак, давайте посмотрим, что происходит:
Отлично, теперь давайте посмотрим на это
__proto__
Перед этим, пожалуйста, помните 2 вещи относительно
__proto__
:Когда вы создаете объект с
new
оператором, его внутреннему[[Prototype]]
/proto__
свойству будет присвоеноprototype
свойство (1) егоconstructor function
или «создателя», если хотите.Жестко закодировано в JS -:
Object.prototype.__proto__
естьnull
.Давайте назовем эти 2 пункта "
bill
"Лучше?
источник
Каждая функция создает свой прототип. И когда мы создаем объект с использованием этого конструктора функции, свойство __proto__ моего объекта начнет указывать на прототип этой функции.
источник
__proto__
собственность.Если все эти цифры были подавляющими, давайте посмотрим, что означают свойства.
STH.prototype
При создании новой функции параллельно создается пустой объект, связанный с функцией
[[Prototype]]
цепочкой. Для доступа к этому объекту мы используемprototype
свойство функции.Имейте в виду, что
prototype
свойство доступно только для функций.STH.constructor
Упомянутый выше объект-прототип не имеет свойств, кроме одного -
constructor
. Это свойство представляет функцию, которая создала объект-прототип.Создавая
Gadget
функцию, мы также создавали подобный объект{constructor: Gadget}
- это совсем не такGadget.prototype
. Какconstructor
относится к функции, создавшей прототип объекта,toy.constructor
представляетGadget
функцию. Мы пишем,toy.constructor.prototype
и мы{constructor: Gadget}
снова получаем .Следовательно, существует замкнутый круг: вы можете использовать,
toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype
и так будет всегдаGadget.prototype
.STH .__ proto__
Хотя
prototype
свойство является специфическим для функций,__proto__
оно доступно для всех объектов в том виде, в котором оно лежитObject.prototype
. Это относится к прототипу функции, которая может создать объект.Здесь
toy.__proto__
естьGadget.prototype
. ТакGadget.prototype
как объект ({}
) и объекты создаются с помощьюObject
функции (см. Пример выше), мы получаемObject.prototype
. Это более высокий объект в JavaScript, и он__proto__
может только указыватьnull
.источник
Краткий ответ:
__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
прототипом, например так:Такой объект является лучше картой (словарь) , чем буквальный объект, поэтому этот образец иногда называют ДИКТ паттерном ( ДИКТ для словаря).
Примечание. Литеральные объекты, созданные с использованием,
{}
являются экземплярами,Object
поскольку({}).__proto__
ссылка является ссылкой наObject.prototype
.источник