views:

90

answers:

3

I am doing OO javascript for the first time. I have read about inheritance and prototype and thought I had cracked it. Until I discovered this little example.

function TestObject(data)
{
    this.test_array = [];
    this.clone_array = [];

    this.dosomestuff = function()
    {
        for(var i=0; i<this.test_array.length; i++)
        {
            this.clone_array[i]=this.test_array[i];
        }
    }   

    this.__construct = function(data)
    {
        console.log("Testing Object Values" ,this.clone_array);
        this.test_array = data;
    };
}

TestObject2.prototype = new TestObject();

function TestObject2(data)
{
    this.__construct(data);
    this.dothings = function()
    {
        this.dosomestuff();
    }
}

If I do the following:

var foo = new TestObject2([1,2,3,4]);
foo.dothings();
var bar = new TestObject2([4,5,6]);
bar.dothings();

I would expect the console to show:

Testing Object Values, []
Testing Object Values, []

However it shows:

Testing Object Values, []
Testing Object Values, [1,2,3,4]

The problem is of course this call:

TestObject2.prototype = new TestObject();

How do I get the parent variables in TestObject to "reset" other than manually resetting them in the __construct method?

Is there another way of TestObject2 of inheriting all the values/methods from TestObject and for "new" to behave as I would expect in a PHP OO manner? (I am sure the way JS is doing this is really really odd as if my brain serves me correctly from University Java works like PHP in this regard)

A: 

have you already tried to define this.clone_array = []; into TestObject2 instead?

function TestObject2(data)
{
    this.clone_array = [];
    this.__construct(data);
    this.dothings = function()
    {
        this.dosomestuff();
    }
}
Fabrizio Calderan
I have 30 variables in my parent. I am extending the parent in 3 different classes. I would have to copy and paste the reset into these 30 classes. Nasty. I would be better off putting them into a reset.
johnwards
A: 

I think

TestObject2.prototype = new TestObject();

is overriding the constructor of TestObject2.

Try

function TestObject2(data)
{
    this.__construct(data);
    this.dothings = function()
    {
        this.dosomestuff();
    }
}


TestObject2.prototype = new TestObject();
TestObject2.prototype.constructor = TestObject2;
JoshNaro
Nope no difference. See: http://jsbin.com/olino3/3
johnwards
+3  A: 

Basically

TestObject2.prototype = new TestObject(); 

places a single instance of TestObject in the prototype chain of TestObject2. Thus, any instances of TestObject2 will modify the same single instance offspring property in TestObject. If you put another console.log in the construtor of TestObject you'll notice it only getting called once!

More details to your exact problem can be found here.

You need to call the constructor of TextObject from within the constructor of TextObject2 like this:

function TestObject2(data)
{
    TestObject.call( this, data);
    this.__construct(data);
    this.dothings = function()
    {
        this.dosomestuff();
    }
}

By calling the TestObject constructor function and executing it in the scope of (this is) the new TestObject2 object, it creates all elements of TestObject in TestObject2 object.

mbrevoort
Excellent, exactly what I was looking for. Have an up vote too!
johnwards
Doh, forgot all about the call into the inherited constructor. Good eye.
JoshNaro