0

I have created collection base class/object to do the repeated task. I have CollectionBase, and I have Persons class that inherit to CollectionBase. but my problem is when i create 2 persons collection like persons1 = new Persons() and persons2 = new Persons() it seems that they have same reference object. Any suggestion on how i can make everytime i will create a new Persons it will create new instance.

Please refer to this on plnkr; http://plnkr.co/edit/8GPkWO4nKRiskxoRWrkg?p=info

(function(){

    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();

})();

3
  • i already make it to work. just what @jfriend00 said put the property to constructor of base class/object. but i want to make the property to be private, so that if someone will use the base class/object they can will force to use the add, remove, and update method. Any suggestions on this? Commented Nov 10, 2014 at 6:50
  • That's an entirely different question. This post on my blog may help: Private properties in ES6 -- and ES3, and ES5. Commented Nov 10, 2014 at 6:53
  • ohh i might take a look on that. as you can see for my previous post of the code it uses Object.defineproperties so that i can configure how does the property behave. Commented Nov 10, 2014 at 6:59

1 Answer 1

3

Any properties assigned to the prototype are shared among all objects that use that prototype (since the prototype object itself is shared among all instances). This is great for functions on the prototype (e.g. methods), but it is usually bad for data properties because (as you have found), all instances share the same data properties which is not what you usually want.

The usual way to handle this is to assign data properties in your constructor, NOT in the prototype. This creates a new data variable for each new instance of the object.

function CollectionBase(){
   // create new value property for each instance
   this.value = [];
}
Sign up to request clarification or add additional context in comments.

10 Comments

To be fair, it's fine for primitives. It's object types that cause the trouble, because they never get reassigned.
Even for arrays it's fine to use the prototype, as when you do a=['a','b'] from the child object, it will not look-up the prototype chain, but directly create a new property in the child object(if not already present), and assign it the value.
@T.J.Crowder - yes, you can put primitives on the prototype, but it's definitely a subtlety to understand what happens when you assign a new value to a primitive that was initially on the prototype. If you just initialize per-instance primitives in the constructor, then you aren't faced with the nuances of that subtlety - life is just simpler.
@Aravind - using the prototype with any object (including an array) will not be a per-instance variable if you just modify the object such as this.a.push("Hello"); That will confused the heck out of someone who doesn't understand the details (such as the OP). Yes, assigning a whole new array to the property will work, but why expose yourself to that complication where modification and assignment work differently. There's rarely a good reason to make your code that subtly complicated.
@jamesemanon - you'd have to show a more complete code example (by editing your question and inserting it there where you can format it too) for me to follow that scenario. In general, ANY array on a prototype is going to be shared by all objects that use that prototype.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.