Tuesday, April 5, 2011

What is the rationale behind the behavior of constructor pointer in JavaScript?

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?

From stackoverflow
  • 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.

  • 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.

    Christoph : `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
    Sergey Ilinsky : 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.
    bobince : +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
    Breton : 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?

0 comments:

Post a Comment