2

i have a base class

function Base(){
    this.children = new Array();
}
Base.prototype.Add = function(child){
    this.children.push(child)
}

function Sub1(){...}
Sub1.prototype = new Base();

function Sub2(){...}
Sub2.prototype = new Base();

so how come when i do

var S1_1 = new Sub1();
var S1_2 = new Sub1();
S1_1.Add(new Sub2());

S1_2 for some reason also has 1 child and contains the same information as the child i added to S1_1?

1
  • Why are you assigning a Base object to prototype? Commented Jun 23, 2013 at 23:15

2 Answers 2

6

It's because that's how prototypal inheritance works. All your Sub1 objects inherit from a common Base object. Because the Base object holds the Array, all Sub1 instances share that Array.

In other words, when you ask for the .children property of each Sub1 object, they will see that they don't own such a property, and will therefore look for it on the prototype from which they inherit. Since they inherit from the same prototype object, they use the same Array.


For each Sub1 to have its own Array, you should define it in the Sub1 constructor.

function Base(){
    this.children = new Array();
}
Base.prototype.Add = function(child){
    this.children.push(child); // `this` will be whatever object invoked the method
}

function Sub1(){
    this.children = [];
}
Sub1.prototype = new Base();

function Sub2(){
    this.children = [];
}
Sub2.prototype = new Base();
Sign up to request clarification or add additional context in comments.

7 Comments

+1 - "Because the Base object holds the Array"
Better: Set up the inheritance with Sub1.prototype = Object.create(Base.prototype); and call Base.call(this) in the child constructors. Using an instance of the parent as prototype only works as long as it does not expect any arguments.
@FelixKling IE 8 doesn't seem to have Object.create. I've added handling constructor parameters and not calling the "parent" constructor when setting prototype to this answer: stackoverflow.com/questions/16063394/… Using goog.inherit
@HMR For this simple use case, a basic polyfill would be enough.
@HMR No, it won't show up in for(hh in myObject), only in for(hh in Object). It's added as an own property of the Object constructor.
|
0

You didn't take ownership/copy of the Base variables defined with this when creating a sub, you can do so with:

function Sub1(){
  Base.call(this);
}

What that code does is calling Base with the Sub1 instance as the this context.

More on prototype behavior can be found here: Prototypical inheritance - writing up

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.