2014-03-14 123 views
1

我有使用原型继承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(); 

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

+0

由于你已经建立了继承,所以'(new Test())。constructor === Baz'。 – RobG

回答

1

在OP,请注意:

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

所以基础构造函数由t.constructor给出。

然而,这是很常见的重新设置这样的建筑遗产时,使每个原型的构造属性指向正确的构造函数(“修复”)的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; 

这意味着布拉德的getRootConstructor功能将不能作为Constructor.prototype.constructor工作始终指向“真实”的构造和

getRootConstructor(Test) === Test; 

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

请注意,如果Brad的函数真的起作用,它将始终返回内置的Function对象,因为它是所有函数的基础构造函数。

+0

你是对的类与构造函数,所以我编辑了这个问题。如果您重新设置prototype.constructor,我的答案会中断,但是否则它会起作用。 –

+0

* prototype *对象的* prototype *属性在其关联的构造函数创建时建立。因为用特定构造函数中的实例替换该* prototype对象,并且不指定构造函数属性,所以从链中任何构造函数创建的每个实例都将继承“base”原型的构造函数,所以'anyInstance.constructor'和'anyConstructor .prototype.constructor'将引用基础构造函数。所以不需要* getRootConstructor *函数。 :-) – RobG

+0

如果你想删除对此类的引用,我将接受它作为答案 –

2

如果您没有设置函数的原型,他们有一个循环引用,使得F.prototype.constructor === F.你想要的功能的话,就是:

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

直到有人与(公共,可变)*构造函数混淆* ... – RobG

相关问题