Reputation: 1479
I have a chain of constructors using prototype inheritance in JavaScript like so:
var Test = function(){};
var Foo = function(){};
var Bar = function(){};
var Baz = function(){};
Bar.prototype = new Baz();
Foo.prototype = new Bar();
Test.prototype = new Foo();
I want to write a function getRootConstructor() such that
getRootConstructor(Test) === Baz.
The goal was that I could do
getRootConstructor(Test).prototype = new UniversalBaseConstructor();
So I could add functionality to a constructor without breaking the prototype chain. This turns out to be very unintuitive.
Upvotes: 1
Views: 255
Reputation: 147453
In the OP, note that:
var t = new Test();
t.constructor == Test; // false
t.constructor == Baz; // true
So the base constructor is given by t.constructor
.
However, it is very common to re–set ("fix") the constructor property when building inheritance like that so that each prototype's constructor property points to the right constructor:
var Test = function(){};
var Foo = function(){};
var Bar = function(){};
var Baz = function(){};
Bar.prototype = new Baz();
Bar.prototype.consructor = Bar;
Foo.prototype = new Bar();
Foo.prototype.constructor = Foo;
Test.prototype = new Foo();
Test.prototype.constructor = Test;
which means that Brad's getRootConstructor function will not work as Constructor.prototype.constructor
always points to the "real" constructor and
getRootConstructor(Test) === Test;
In this case it is also common to add a _super
(or similar named) property to each prototype that points to the prototype's constructor, so the base constructor could be found that way.
Note that if Brad's function really worked, it would always return the built–in Function object, as it is the base constructor for all functions.
Upvotes: 1
Reputation: 1479
If you don't set the prototype of a function, they have a circular reference such that F.prototype.constructor === F. The function you want, then, is:
function getRootConstructor(T){
return T.prototype.constructor === T ? T : getRootConstructor(T.prototype.constructor);
}
Upvotes: 2