Brad Urani
Brad Urani

Reputation: 1479

How do you find the root prototype constructor for a constructor in a prototype chain?

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

Answers (2)

RobG
RobG

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

Brad Urani
Brad Urani

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

Related Questions