views:

81

answers:

2

Hi all,

This is about "inheritance" in JavaScript.

Supose I create a constructor Bird(), and another called Parrot() which I make to "inherit" the props of Bird by asigning an instance of it to Parrot's prototype, like the following code shows:

function Bird() {
    this.fly = function(){};
}

function Parrot() {
    this.talk = function(){ alert("praa!!"); };
}
Parrot.prototype = new Bird();

var p = new Parrot();

p.talk(); // Alerts "praa!!"
alert(p.constructor); // Alerts the Bird function!?!?!

After I've created an instance of Parrot, how comes that the .constructor property of it is Bird(), and not Parrot(), which is the constructor I've used to create the object?

Thanks!!

+1  A: 

The constructor refers to the function that creates an instance's prototype (rather than the instance).

machine elf
+2  A: 

Prototype is an object just like anything else in JavaScript and object assignments are by reference. You just assigned a new bird to parrot's prototype so parrot's prototype is now a bird instance. And a bird's constructor is Bird.

You could fix this with the line

Parrot.prototype.constructor = Parrot;

Another way to do this would be to assign a clone of Bird's prototype to Parrot.prototype

function deepClone(obj) {
    var clone = {};
    for(var i in obj) {
        if(typeof(obj[i])==="object") {
            clone[i] = deepClone(obj[i]);
        } else {
            clone[i] = obj[i];
        }
    }
    return clone;
}


Parrot.prototype = deepClone(Bird.prototype);
Parrot.prototype.constructor = Parrot;

I prefer this because:

1) it saves creating an arbitrary instance of bird (what if something is counting hwo many birds have been created)

2) What if Bird constructor took an argument which was tested in the constructor body? Then calling:

Parrot.prototype = new Bird();

could then cause a null pointer

plodder
Ah! I finally get it :pParrot.prototype, a Bird instance with .constructor already defined (equal to Bird), is used in Parrot to create the new instance.What seems strange to me is that .constructor is not automatically overridden. Anyway, knowing it makes it easy to solve (like you proposed).Thanks a lot!
nandinga