2015-11-02 2 views
1

Может ли кто-нибудь объяснить, что будет дальше, когда я o1.set('bar');? Мне интересно, почему o2.name также установлен в это время, и то же самое не происходит, когда я o2.set('fox');, я имею в виду, o1.name остается bar.Использование Javascript указателей Object.create и свойств не разыменовывается из прототипа

Почему o1.name и o2.name указывают на тот же объект, хотя я изменил старое значение (foo), но то же самое не происходит, когда я изменяю o2.name?

var Person = { 
 
\t name: "foo", 
 
\t get: function get() { 
 
\t \t return this.name; 
 
\t }, 
 
\t set: function set(sur) { 
 
\t \t this.name = sur; 
 
\t } 
 
}, 
 
o1 = Person, 
 
o2 = Object.create(o1); 
 

 
// true "foo" "foo" 
 
console.log(o1.name === o2.name, o1.get(), o2.get()); 
 

 
o1.set('bar'); 
 

 
// true "bar" "bar" 
 
console.log(o1.name === o2.name, o1.get(), o2.get()); 
 

 
o2.set('fox'); 
 

 
// false "bar" "fox" 
 
console.log(o1.name === o2.name, o1.get(), o2.get());

Другой поведение можно увидеть ниже. Разница здесь в том, что я продлеваю прототип Person даже для объекта o1.

\t var Person = { 
 
\t \t name: "foo", 
 
\t \t get: function get() { 
 
\t \t \t return this.name; 
 
\t \t }, 
 
\t \t set: function set(sur) { 
 
\t \t \t this.name = sur; 
 
\t \t } 
 
\t }, 
 
\t o1 = Object.create(Person), 
 
\t o2 = Object.create(Person); 
 

 
\t // true "foo" "foo" 
 
\t console.log(o1.name === o2.name, o1.get(), o2.get()); 
 

 
\t o1.set('bar'); 
 

 
\t // false "bar" "foo" 
 
\t console.log(o1.name === o2.name, o1.get(), o2.get()); 
 

 
\t o2.set('fox'); 
 

 
\t // false "bar" "fox" 
 
\t console.log(o1.name === o2.name, o1.get(), o2.get());

ответ

1

Ответ можно найти в хороших «программирования JavaScript приложений» книга по Эрик Эллиот, и я думаю, что эту проблему можно найти здесь Delegate Prototypes.

Эрик говорит, что:.

"В JavaScript объекты имеет внутреннюю ссылку на делегат прототип Когда объект запрашивается для свойства или методы, двигатель JavaScript сначала проверяет объект Если ключ Безразлично. . «т существует на этом объекте, он проверяет, делегат прототип, и так далее по цепочке прототипов цепь прототипа обычно заканчивается в прототипе объекта

и завершает explannation с:

“. недвижимости на прото тип действует как значения по умолчанию. Когда вы устанавливаете их в экземпляре, значение экземпляра только переопределяет значение для этого экземпляра. "

Другими словами, я понял, что, когда вызов o1.get() я меняю прототип и o2 объекта расширяет его. Тем не менее, когда я называю o2.get() я не меняющийся прототип больше, но экземпляр o2. Вот почему после того, как что любое изменение на o1.name теперь отключено от o2.name.

4

Объект o2наследует "имя" свойства от своего прототипа цепи. Однако, как только свойство будет установлено, это затронет сам объект.

Другими словами, при установке свойства объекта не проецируется цепочка прототипов. Свойство, обновленное (или добавленное), всегда находится на целевом объекте напрямую. Цепочка прототипа рассматривается только при проверке значений свойств.

Это в вызове o2.set("fox"); Функция set() сама по себе находится на прототипе. Однако значение в этом вызове составляет o2, а не o1, поэтому назначение this.name напрямую влияет на o2.

+0

очень хороший @Pointy не могли бы вы добавить некоторые ссылки по этой теме, которые объясняются глубоко? – thiagoh

+0

@thiagoh Я не знаю какой-либо конкретной ссылки для этого поведения; это то, как язык работает. – Pointy

Смежные вопросы