2014-11-20 5 views
1

рассмотрит фрагмент кодаjavascript: как точно свойства, унаследованные от прототипа?

function F(){ 
    this.p=10; 
} 
F.prototype.newProp='some value'; 
var f1=new F(), f2=new F(); 

alert(f1.__proto__==f2.__proto__); //returns true. implies f1 and f2 share same instance of prototype object 

f1.newProp='new value'; //changing the value of inherited property 
alert(f2.newProp); //returns 'some value' 

Ok теперь вопрос, если f1 и f2 как один и тот же [[прототип]] экземпляра объекта и если поиска недвижимости в JavaScript работает, идя по цепочке прототипов

Так что, если я изменяю значение свойства (newProp, в данном случае) общего объекта [[prototype]], , то как его не отразилось и на f2, с f1. proto == f2. прото (что означает его же объект) , то почему изменение newProp Ф1 не меняет newProp из f2 (оба наследуют от того же объекта-прототипа, нет?)

Удивительно, но изменения f1. proto .newProp отражает изменение при извлечении «f1.newProp»

Итак, f1.newProp и f1. proto .newProp различные свойства?

Я думал, что свойство ищет в javascript, работающем последовательно, выглядящим выше в цепочке прототипов.

Я прошу прощения, если мой вопрос звучит наивно, но я не мог получить мою голову вокруг:

Если 1) f1. proto == f2. proto // true! подразумевает как объекты f1 и f2 см же [[Prototype]] объекта, из которого они наследуют

и если

2) свойство не найдено в объекте ищется в прототипе.

, то почему изменение f1.newProp не отражает в f2.newProp тоже? поскольку оба имеют общее свойство [[prototype]], как показано в пункте (1)

Является ли это, что свойства объекта прототипа копируются индивидуально в f1 и f2. ? , но затем это нарушает точку (2) [поиск свойств цепи прототипа, если не найден в объекте]

Пожалуйста, объясните это противоречие здесь. спасибо у очень много :)

================== EDIT ================

благодарственное вы @ jfriend00 за ответ.

но позволяет сказать, что у меня есть этот код

function Person(name, age){  
    this.name=name; 
    this.age=age; 
    alert("obj created:"+name); 
} 
function Employee(name,age,eid){ 
    this.base=Person; 
    this.base(name,age); 
    this.eid=eid; 
} 
Employee.prototype=new Person; 

var ob1=new Employee('name1',23,100); 
var ob2=new Employee('name2',24,101); 

здесь, очевидно, ob1. proto == ob2.прото , но если я не ошибаюсь, есть 2 объекта здесь для каждого экземпляра сотрудника

1 объект работник сам только 1 собственности Ид (и другой один базовый FUNC)

второй является объектом Person на который ссылается свойство [[prototype]] объекта employee. Этот объект имеет имя и возрастное свойство. Таким образом, сотрудник obj фактически сохраняет и возвращает имя и возраст из своего объекта [[prototype]] Person. Я прав?

Если да, и с ob1. proto == ob2. proto, то как мы можем хранить уникальное имя и возраст обоих объектов?

Я имею в виду, здесь почти кажется, что для каждого сотрудника существует прототип объекта. , если и может объяснить это, спасибо у очень много :)

и еще один запрос:

как же приведенный выше код будет работать, даже если закомментировать

Employee.prototype=new Person; 

в выше линии и тем самым нарушая связь между двумя объектами. Наследование все еще работает только потому, что я объявил функцию Person как свойство Employee и вызвал Person из него. как это работает спасибо :)

+0

На вашем дополнительном коде, вам нужно вызвать конструктор базового объекта из производного конструктора объекта, чтобы он мог выполнять свою надлежащую инициализационные работу на вновь созданный объект 'Person.call (это , имя, возраст). Я не знаю, какую ссылку вы изучаете, но любая хорошая ссылка на наследование в Javascript должна показать вам это, так что это, вероятно, в любой ссылке, которую вы используете. – jfriend00

+0

ОК, но вы можете объяснить мой оригинальный вопрос об отредактированной части. Как ob1 и ob2 используют один и тот же прототип объекта, но оба имеют разные свойства имени и возраста, которые сами хранятся в объекте прототипа. спасибо – Sarabjeet

+0

Какой вопрос? Вы задали много вопросов, и я не знаю, с кем вам по-прежнему нужна помощь. Прототип нужен, только если вы на самом деле используете что-либо на нем. Если вы его не используете, вам не нужно устанавливать его, потому что в любом случае у него ничего нет. – jfriend00

ответ

1

Объект-прототип разделяется между всеми объектами (как вы показали).

Но, когда вы назначаете свойство и объект, он не меняет прототип, свойство переходит к самому объекту и из-за порядка поиска для разрешения ссылки на свойство вновь назначенное свойство на объекте сам обнаруживается до того, что находится на прототипе, поэтому он становится активным свойством.

Когда вы ссылаетесь на свойство на объекте, есть порядок поиска. Сначала он ищет свойства непосредственно на объекте. Если совпадение не найдено, он ищет цепочку прототипов.

Когда вы пишете свойство на объекте, оно никогда не записывается в прототип, если вы явно не ссылаетесь на объект прототипа, вместо этого он помещает свойство непосредственно в объект, и это свойство становится активным (по существу, переопределяя то, что включено Прототип).

Вы можете определить, находится ли свойство на самом объекте или на прототипе, используя .hasOwnProperty(). Это вернет true только тогда, когда свойство находится непосредственно на объекте.

Таким образом, в вашем коде:

f1.newProp='new value'; //changing the value of inherited property 

Это добавляет новое свойство непосредственно к объекту (не на прототипе), и это существенно перекрывает то, что на прототипе.


В общем, свойства данных обычно задаются в конструкторе, чтобы избежать путаницы о двух возможных местах свойство может находиться и, если вы пишете на них, то на самом деле никаких преимуществ имея первоначально указано их на прототипе. Функциональные свойства (например,методы) часто устанавливаются в прототипе, потому что они, как правило, не записываются, поэтому более эффективно просто иметь один общий объект прототипа, который содержит их, которые можно прочитать.

+0

Большое вам спасибо. , но позволяет сказать, что у меня есть этот код 'code' function Person (имя, возраст) { this.name = name; this.age = age; alert ("obj created:" + name); } function Employee (имя, возраст, eid) { this.base = Person; this.base (имя, возраст); this.eid = eid; } Employee.prototype = новое лицо; var ob1 = new Employee ('name1', 23,100); var ob2 = new Employee ('name2', 24,101); 'code' // ob1 .__ proto__ == ob2 .__ proto__ is true – Sarabjeet

+0

@Sarabjeet - многострочный код не читается в комментариях. Вы можете использовать ссылку редактирования на своем оригинальном посте, чтобы разместить то, о чем вы просите, а затем опубликовать комментарий, чтобы привлечь внимание к новому коду. – jfriend00

+0

@Sarabjeet - вы редактируете свой собственный пост с помощью своего дополнительного кода, а не моего. – jfriend00

1

Как только вы установили f1.newProp = 'new value', он больше не устанавливает newProp на прототипе, а на самом объекте f1. Попробуйте это, вы увидите:

var f1=new F(), f2=new F(); 
console.log(f1.hasOwnProperty('newProp')); // returns false, because it is from prototype 
f1.newProp = 'new value'; 
console.log(f1.hasOwnProperty('newProp')); // returns true 
+0

спасибо Deitch :) – Sarabjeet

+0

С удовольствием. :-) – deitch

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