22

I've recently started reading up on OOP javascript and one thing that authors seem to skip over is when an object A has been declared and suddenly I see "A.prototype.constructor =A; For example,

var A = function(){}; // This is the constructor of "A"
A.prototype.constructor = A;
A.prototype.value = 1;
A.prototype.test = function() { alert(this.value); }
var a = new A(); // create an instance of A
alert(a.value);  // => 1

So I run the command in firebug "var A = function(){};" and then "A.Constructor" Which reveals it's a function. I understand this.
I run the code "A.prototype.constructor = A;" and I thought this changes the A constructor from Function to A.

The constructor property of A has been changed right? Instead when I run "A.constructor" it gives me function () still.

What's the point?

I also see A.constructor.prototype.constructor.prototype.. what is going on?

uzay95
  • 16,052
  • 31
  • 116
  • 182
Matt
  • 2,439
  • 7
  • 29
  • 42

5 Answers5

12

If A inherit B using A.prototype = new B();, you need to reset the constructor property for the class A using A.prototype.constructor=A;, otherwise instances of A would have a constructor of B.

In your case, A.prototype.constructor === A will return true, so A.prototype.constructor = A did nothing.

xdazz
  • 158,678
  • 38
  • 247
  • 274
  • Interesting so A.prototype.constructor=A; would make A isolate itself from B? This way, you can extend more properties using A.prototype without adding more properties to B? – Matt Feb 02 '12 at 08:12
  • It's nothing about isolate, it's just make sure A has the right constructor property. – xdazz Feb 02 '12 at 09:42
  • 11
    What is the purpose of having the right constructor property? When is A.prototype.constructor ever actually consulted in practice? It does not seem to affect the behavior of creating new instances of A, afaics. The answer must be so obvious that it's generally unstated, which is why it has eluded me :-) – Yetanotherjosh Jul 30 '13 at 06:40
4

You can quickly test out that that additional assignment does absolutely nothing:

var A = function() {};
A.prototype.constructor === A; // true -- why assign then?

Resetting the constructor property only makes sense if you've assigned a new prototype object to the class, overwriting the original constructor:

var A = function() {};
A.prototype = protoObject; // some object with members that you'd like to inherit
A.prototype.constructor = A; // reset constructor

In your case, the author might be blindly doing this as good practice, even in cases where it's not necessary.

Ates Goral
  • 137,716
  • 26
  • 137
  • 190
2

This code if often use in JS classic inheritance pattern (the code is from JavaScript Patterns by Stoyan Stefanov):

function inherit(C, P) { 
    var F = function () {}; 
    F.prototype = P.prototype; 
    C.prototype = new F(); 
    C.uber = P.prototype; 
    C.prototype.constructor = C; 
} 

to assign right constructor to the child class.

In your case it did nothing, since A.prototype.constructor === A before assignment.

bjornd
  • 22,397
  • 4
  • 57
  • 73
1

You might want to see my answer to similar question:

https://stackoverflow.com/a/19616652/207661

TL;DR: constructor is not an own property of an instance. So to make things look consistent JavaScript interpreter needs to set prototype.constructor to function itself. This feature can be used in functions that operates generically on many different types of objects.

Community
  • 1
  • 1
Shital Shah
  • 63,284
  • 17
  • 238
  • 185
1

According to MDN, All objects inherit a constructor property from their prototype:

Example 1:
var o = {};
o.constructor === Object; // true

..

Example2:
function Tree() {  
}    
var theTree = new Tree();
console.log(theTree.constructor === Tree ); // true

At runtime, it does not make any difference based on the value of the constructor property.

However, as the constructor property returns a reference to the Object function that created the instance's prototype, one should reset the constructor property when they assign a new prototype to the Object function.

var Forest = function() {};
Forest.prototype = theTree;  
console.log(new Forest().constructor === Tree ); // true
Forest.prototype.constructor = Forest;  
console.log(new Forest().constructor === Forest ); // true

https://jsfiddle.net/j1ub9sap/

For details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

Razan Paul
  • 13,618
  • 3
  • 69
  • 61
  • Hi, I jump on your comment a few months later because I don't understand this sentence : "However, as the constructor property returns a reference to the Object function that created the instance's prototype" The Object function does not create the instance's prototype, it creates the instance directly no ? What does it mean exactly ? Thanks – jobou Jul 07 '16 at 12:46
  • It means that If Forest inherit theTree using Forest.prototype = new theTree(), instances of Forest will have a constructor of theTree. To have Forest as a constructor, one need to reset the constructor property for Forest using Forest.prototype.constructor=Forest. – Razan Paul Jul 07 '16 at 23:00
  • I understand your example. My question was more about the official documentation : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor It says "Returns a reference to the Object function that created the instance's prototype.". However all the examples in this page don't have their prototype overriden. There is no custom inheritance : `var a = []; a.constructor === Array;` So why doesn't it say that "the constructor is the reference to the Object function that created the instance itself" ? Thanks – jobou Jul 08 '16 at 07:50