0

Possible Duplicate:
Why is it necessary to set the prototype constructor?

I'm struggling to understand the necessity of setting the 'constructor' property of a javascript object to the subclass when building a hierarchy. I find that the code below does what is expected without changing the constructor property, but in almost all references I find about the subject the constructor is set explicitly. Am I missing something ? (I don't find any explicit use of it in the ECMAScript specs either).

A = function() {
    this.value = "a";

    this.A = function() {
        window.alert( this.value + " instanceof A : " + ( this instanceof A ) );
    }
}


B = function() {
    this.value = "b";

    this.B = function() {
        window.alert( this.value + " instanceof B : " + ( this instanceof B ) );
    }
}

B.prototype = new A();

test = function() {
    var b = new B();
    b.A();
    b.B();
}
Community
  • 1
  • 1

1 Answers1

1

First of all, proper JS inheritance means putting methods in the prototype:

var A = function() {
    this.value = "a";
};

A.prototype.A  = function() {
        window.alert( this.value + " instanceof A : " + ( this instanceof A ) );
};

var B = function() {
    this.value = "b";
};

Secondly, don't run the constructor when establishing a prototype chain:

B.prototype = Object.create( A.prototype );

Whenever you reassign the entire .prototype, you are completely overwriting the object. So the constructor property needs (If it's going to be used) to be reassigned:

B.prototype.constructor = B;

B.prototype.B = function() {
    window.alert( this.value + " instanceof B : " + ( this instanceof B ) );
};

Object.create is not supported in older browsers but you can do something like:

Object.create = Object.create || function( proto ) {
     if( proto == null ) {
         return {};
     }
     function f(){}
     f.prototype = proto;
     return new f();
};
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • 2
    It's only necessary to set the `constructor` property if your code has some expectation of using it. Personally I find it entirely useless. – Tim Down Nov 24 '12 at 13:57
  • @TimDown not necessarily your code, iirc, the es5-shim requires constructor property to be set for `getPrototypeOf` – Esailija Nov 24 '12 at 13:58
  • That's not a proper shim then. – Tim Down Nov 24 '12 at 14:00
  • @TimDown yeah I tried to find the code and it has now been moved to es5-sham.js :P Anyways I have edited in that it's only needed if constructor is going to be used. – Esailija Nov 24 '12 at 14:01
  • @Timdown, Thanks ! that's what I figured as well, but wasnt sure. – Jochem Van Der Spek Nov 24 '12 at 15:29
  • @Esailija Thanks a lot for your answer, I understand now that because I create a new object for the prototype that the constructor is overwritten. shouldve seen that myself. I'm new to JS from C++ and am a bit baffled by the amount of different ways that ppl approach this. your insights helped a lot. – Jochem Van Der Spek Nov 24 '12 at 15:32
  • @Esailija, by the way, why is it that "proper JS inheritance means putting methods in the prototype", but the approach I used for the example code works fine, what is 'improper' about that ? – Jochem Van Der Spek Nov 24 '12 at 15:38
  • @JochemVanDerSpek If you create functions in a constructor, those functions are recreated (Recreation = creating a new function object and referencing environment) every time the constructor is called (so every time you create an instance) whereas with a function in prototype, that function is reused. It works fine for now because you are not using any state, if you were to define variables in the constructor and then reference them in methods, all the instances of B would actually share the same inherited state. Also, see http://jsfiddle.net/bUyBa/ – Esailija Nov 24 '12 at 16:01
  • @Esailija Yes, that figures & makes sense ! thanks. – Jochem Van Der Spek Nov 24 '12 at 16:32