如何为原型链中的构造函数找到根原型构造函数?

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

本文关键字:原型 构造函数      更新时间:2023-09-26

我有一个使用JavaScript原型继承的构造函数链,如下所示:

var Test = function(){};
var Foo = function(){};
var Bar = function(){};
var Baz = function(){};
Bar.prototype = new Baz();
Foo.prototype = new Bar();
Test.prototype = new Foo();

我想写一个函数getRootConstructor(),这样

getRootConstructor(Test) === Baz.

目标是我可以做

getRootConstructor(Test).prototype = new UniversalBaseConstructor();

所以我可以在不破坏原型链的情况下向构造函数添加功能。这是非常不直观的

如果你不设置一个函数的原型,它们有一个循环引用,如F.prototype.constructor === F.那么你想要的函数是:

function getRootConstructor(T){
 return T.prototype.constructor === T ? T : getRootConstructor(T.prototype.constructor);
}

在OP中,请注意:

var t = new Test();
t.constructor == Test; // false
t.constructor == Baz;  // true

基本构造函数由t.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;

这意味着Brad的getRootConstructor函数不能工作,因为Constructor.prototype.constructor总是指向"真正的"构造函数和

getRootConstructor(Test) === Test;

在这种情况下,为每个指向原型构造函数的原型添加一个_super(或类似命名的)属性也是很常见的,这样就可以通过这种方式找到基础构造函数。

注意,如果Brad的函数真的有效,它将总是返回内置的function对象,因为它是所有函数的基本构造函数。