__proto__
Вы действительно можете получить доступ к внутреннему [[Prototype]]
свойства объекта с __proto__
. Вы можете представить [[Prototype]]
как фактический родитель текущего объекта в иерархии наследования.
prototype
Это особое свойство, когда установлено на функцию (конструктор) объекта, используемого для установления цепи наследования для экземпляров, созданных из конструктора. Например,
function Foo() {}
Foo.prototype = {a: 1};
Теперь, когда вы создаете новый объект типа Foo
, внутренняя [[Prototype]]
собственности вновь созданный объект будет ссылаться на Foo.prototype
объекте. Вы можете подтвердить, что как этот
console.assert((new Foo()).__proto__ === Foo.prototype);
В вашем случае,
myFunc.prototype = myObj;
вы создаете prototype
свойство на объекте функции, и это будет использоваться только при создании новых объектов с эта функция (функция конструктора). Вы можете подумать об этом как о шаблоне для новых объектов. Итак, когда вы делаете myFunc.a
, JS-движок пытается найти a
в myFunc
и его родителям в цепочке прототипов, и он не находит его, поэтому он возвращает undefined
.
Но, когда вы делаете
myFunc.__proto__ = myObj;
вы устанавливаете родительский myFunc
в цепочке прототипов, чтобы myObj
. Итак, когда вы делаете myFunc.a
, JS-движок сначала пытается найти a
в myFunc
самом объекте, и его там нет. Таким образом, он пытается найти его у своего непосредственного родителя, который равен myObj
. Поэтому в этом случае он возвращает 1
.
Примечание: Вы можете использовать следующую функцию, чтобы понять цепочку прототипов лучше
function printPrototypeChain(object) {
while (object !== null) {
console.log(object);
object = Object.getPrototypeOf(object);
}
}
Теперь, давайте печатать цепочку прототипов, когда объект установлен как prototype
свойства функции объект.
function myFunc() {}
myFunc.prototype = {
a: 1,
b: 2
};
printPrototypeChain(myFunc);
Вывод будет
[Function: myFunc]
[Function: Empty]
{}
Ни один из этих объектов не имеют определенного a
, поэтому undefined
возвращается. Но, в этом случае,
function myFunc() {}
myFunc.__proto__ = {
a: 1,
b: 2
};
printPrototypeChain(myFunc);
прототип цепь становится как этого
[Function: myFunc]
{ a: 1, b: 2 }
{}
и a
находится в непосредственном родителе myFunc
«s. Таким образом, возвращается соответствующее значение 1
.
Примечание: Не используйте __proto__
в вашем фактическом коде, так как он сохранен в последних версиях спецификации JavaScript только для обратной совместимости. Узнайте больше об этом here. Вместо этого используйте Object.getPrototypeOf
и Object.setPrototypeOf
.
http://es5.github.io/ ничего не знает о '__proto__' вообще. Это означает, что он не является частью стандарта, и вы никогда не должны его использовать. – zerkms
Нет, прототип объекта (тот, который он наследует) - это ** не ** '.prototype'. Вы прочитали все ответы на http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript? Что конкретно вы не поняли (мы рады их улучшить)? – Bergi
то что такое .prototype, используемый для ?? – Flake