Согласно спецификациям ECMA Script 5 ,
Значение свойства
blockquote>prototype
используется для инициализации внутреннего свойства[[Prototype]]
для вновь созданного объекта перед тем как объект Function вызывается как конструктор для этого вновь созданного объекта.Понятно, что
prototype
просто инициализирует свойство[[Prototype]]
. Когда мы создаем объект,[[Prototype]]
устанавливается как объектprototype
функции конструктора и устанавливается цепочка прототипов. В вашем случае, когда вы делаетеvar obj = function() {}; obj.prototype.x = 5; var instance1 = new obj();
,
[[Prototype]]
выглядит такconsole.log(Object.getPrototypeOf(instance1)); # { x: 5 }
(Да, вы можете получить доступ к
[[Prototype]]
с помощьюObject.getPrototypeOf
]Итак, когда JS Engine ищет
x
вinstance1
, он находит значение как5
, а посколькуy
не определен, он используетundefined
.Во втором случае
obj.prototype = {y: 6}; var instance2 = new obj();
вы меняете объект
prototype
объектаobj
, так что новые объекты, построенные с помощью этих функций, будут использовать новый объект, назначенный ему. Таким образом,[[Prototype]]
выглядит так:instance2
console.log(Object.getPrototypeOf(instance2)); # { y: 6 }
Вот почему
instance2
не смог найти в немx
, ноy
.Чтобы ответить на обновленный вопрос,
EDIT: Как я могу изменить прототип всех экземпляров?
blockquote>Вы можете изменить , прототип старого объекта с
Object.setPrototypeOf
, как этоObject.setPrototypeOf(instance1, { y: 6 });
Так как это
[[Prototype]]
instance1
отличается отinstance2
, мы можем просто обновить функцию конструктораprototype
, напримерdelete obj.prototype.x; obj.prototype.y = 6;
Теперь мы не изменили внутреннего свойства как
instance1
, так иinstance2
. Мы можем проверить, что такconsole.log(Object.getPrototypeOf(instance1) === Object.getPrototypeOf(instance2)); # true console.log(Object.getPrototypeOf(instance1) === obj.prototype); # true
Примечание: Соглашение должно называть функции-конструкторы с начальной буквой заглавной буквой.