2014-11-10 4 views
0

Я создал коллекцию базового класса/объекта для выполнения повторной задачи. У меня есть CollectionBase, и у меня есть класс Person, который наследует CollectionBase. но моя проблема заключается в том, когда я создаю коллекцию из двух человек, например people1 = new Persons() и persons2 = new Persons(), похоже, что у них есть один и тот же ссылочный объект. Любое предложение о том, как я могу делать каждый раз, я создам новых лиц, создающих новый экземпляр.javascript prototype inheritance override property

См. Это на plnkr; http://plnkr.co/edit/8GPkWO4nKRiskxoRWrkg?p=info

(функция() {

function CollectionBase(){ 
    this.collection = []; 
} 

Object.defineProperties(CollectionBase.prototype, { 
    count: { 
     get: function(){ 
      return this.collection.length; 
     }, 
     enumerable: true 
    } 
}); 

CollectionBase.prototype.init = function(){ 
}; 

CollectionBase.prototype.get = function(index){ 
    if (index === undefined){ 
     return this.collection; 
    } 
    return this.collection[index]; 
}; 

CollectionBase.prototype.remove = function(index){ 
    try{ 
     if (index === undefined) throw new Error('index is undefined'); 
     this.collection.splice(index, 1); 
    } 
    catch(err){ 
     console.log(err);  
    } 
}; 

CollectionBase.prototype.update =function(item){ 
}; 

CollectionBase.prototype.add = function(item){ 
    this.collection.push(item); 
}; 


function Person(firstName, lastName){ 
    this.firstName = firstName; 
    this.lastName = lastName; 
} 

function Persons(){ 
    CollectionBase.call(this); 
} 

Persons.prototype = Object.create (CollectionBase.prototype);

var persons1 = new Persons(); 
var persons2 = new Persons(); 

})();

+0

Я уже заставляю его работать. просто то, что @ jfriend00 сказал, помещает свойство в конструктор базового класса/объекта. но я хочу, чтобы свойство было приватным, так что, если кто-то будет использовать базовый класс/объект, он может заставить использовать метод добавления, удаления и обновления. Любые предложения по этому поводу? – yajra

+0

Это совершенно другой вопрос. Это сообщение в моем блоге может помочь: [* Частная собственность в ES6 - и ES3 и ES5 *] (http://blog.niftysnippets.org/2013/05/private-properties-in-es6-and-es3- and.html). –

+0

Ох я могу взглянуть на это. как вы можете видеть для моего предыдущего поста кода, он использует Object.defineproperties, чтобы я мог настроить способ поведения. – yajra

ответ

3

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

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

function CollectionBase(){ 
    // create new value property for each instance 
    this.value = []; 
} 
+0

Справедливости ради, это нормально для примитивов. Это типы объектов, которые вызывают проблемы, потому что они никогда не переназначаются. –

+0

Даже для массивов хорошо использовать прототип, так как когда вы делаете a = ['a', 'b'] из дочернего объекта, он не будет искать цепочку прототипов, а непосредственно создает новое свойство в дочернем объекте объект (если он еще не присутствует) и присвоить ему значение. – Aravind

+0

@ T.J.Crowder - да, вы можете поместить примитивы в прототип, но это определенно тонкость, чтобы понять, что происходит, когда вы назначаете новое значение примитиву, который был первоначально на прототипе. Если вы просто инициализируете примитивы для каждого экземпляра в конструкторе, то вы не сталкиваетесь с нюансами этой тонкости - жизнь просто проще. – jfriend00