tags:

views:

163

answers:

2

Considering the simplistic scenario:

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

I wonder why would an instance of Child have constructor property set to Base and not to Child?

+4  A: 

It's all tied to how inheritance works in JavaScript. Check this link for a detailed explanation (basically, constructor is just another property of the prototype).

Edit: Also, if you want 'real' prototypical inheritance, you have to use some sort of clone function, eg

function clone(obj) {
    if(typeof obj !== 'undefined') {
        arguments.callee.prototype = Object(obj);
        return new arguments.callee;
    }
}

Then, you can do things like this

function Base() {}
function Sub() {}
Sub.prototype = clone(Base.prototype);

var obj = new Sub;

and you'll still get true two times on

document.writeln(obj instanceof Sub);
document.writeln(obj instanceof Base);

The difference to your solution is that Base() won't be called and Sub.prototype will only inherit the properties of Base.prototype - and not the ones set in the constructor.

Christoph
+2  A: 
function Base() {}
//Base.prototype.constructor === Base
function Child() {}
//Child.prototype.constructor === Child;
var b = new Base;
//b.constructor = Base;
Child.prototype = b;
//Child.prototype.constructor === Base

basically, any property of the prototype becomes a property of the instance, including "constructor"

when you reassign the whole prototype property to a new object, you're replacing the old constructor property with the new one.

if you don't want this to happen, you have to assign properties to the prototype object one by one, instead of assigning the whole prototype property to a new object at once. Or replace the old constructor property afterward.

Much better idea: don't rely on the constructor property for anything important.

Breton
`instanceof` is perfectly safe to use if you know what you're doing: `obj instanceof Func` is the same as `Func.prototype.isPrototypeOf(obj)`; all it does is check the [[Prototype]] chain for a specific object - perfectly reasonable in a language with prototypical inheritance
Christoph
I would argue on your recommendation not to rely on usage of instanceof. It works perfectly and does exactly what it is supposed to do.
Sergey Ilinsky
+1 on "don't rely on the constructor property", it is not standard/globally available and doesn't work the way it looks like. More: http://stackoverflow.com/questions/402538/convention-for-prototype-inheritance-in-javascript
bobince
what the, I had the "instanceof" remark in my answer for about 2 minutes, realized on my own that I was going overboard, and edited it out. Now I come back the next day and find comments saying that I'd gone too far? How weird, is there something wrong with stackoverflow? edits not taking effect?
Breton