【问题标题】:How do you find the root prototype constructor for a constructor in a prototype chain?如何在原型链中找到构造函数的根原型构造函数?
【发布时间】:2014-03-14 00:40:33
【问题描述】:

我有一个在 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();

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

【问题讨论】:

  • 由于您建立继承的方式,(new Test()).constructor === Baz

标签: javascript oop prototype


【解决方案1】:

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

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

【讨论】:

  • 直到有人弄乱了(公共的,可变的)构造函数
【解决方案2】:

在 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;

这意味着 Brad 的 getRootConstructor 函数将不起作用,因为 Constructor.prototype.constructor 总是指向“真正的”构造函数并且

getRootConstructor(Test) === Test;

在这种情况下,也很常见将_super(或类似名称)属性添加到指向原型构造函数的每个原型,因此可以通过这种方式找到基本构造函数。

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

【讨论】:

  • 你对类与构造函数是对的,所以我编辑了这个问题。如果您重新设置prototype.constructor,我的答案确实会中断,但否则它会起作用。
  • prototype 对象的 prototype 属性是在创建其关联的构造函数时建立的。因为你用来自特定构造函数的实例替换了那个 prototype 对象并且没有分配构造函数属性,所以从链中的任何构造函数创建的每个实例都将继承“基础”原型的构造函数,所以anyInstance.constructoranyConstructor.prototype.constructor 将引用基本构造函数。所以不需要 getRootConstructor 函数。 :-)
  • 如果您想从中删除对类的引用,我会接受它作为答案
  • 既然你从 OP 中删除了类... :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-28
  • 2019-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多