javascript:创建一个继承自多个构造函数原型的对象

时间:2010-11-22 12:15:26

标签: javascript inheritance prototype constructor

说我有两个构造函数:

A = function () {
    this.x = 'x';
};
A.prototype.a = 'a';

B = function () {
    this.y = 'y';
};
B.prototype.b = 'b';

如何创建将继承自的对象 ab 两者的原型?所以下面的例子将起作用:

ab.a === 'a'; // true
ab.b === 'b'; // true
A.prototype.a = 'm';
ab.a === 'm'; // true
B.prototype.b = 'n';
ab.b === 'n'; // true

由于

2 个答案:

答案 0 :(得分:7)

你不能,只有一个原型链。你基本上有三个选择:

继承一个,复制另一个

单个对象上具有属性方面所能做的就是从其中一个原型继承并复制另一个的属性。显然,这并不是你想要的,因为你没有复制属性的实时参考方面,但你可以在单个对象上拥有这些属性。

组合物

另一种选择是组合

var ab = {
    aness: new A(),
    bness: new B()
};

ab.aness.a === 'a'; // true
ab.bness.b === 'b'; // true
A.prototype.a = 'm';
ab.aness.a === 'm'; // true
B.prototype.b = 'n';
ab.bness.b === 'n'; // true

现在,ab作为A方面(称之为“A-ness”)在其aness属性和B方面(称之为“B-ness”)在bness属性中。

当人们认为“我需要多重继承”时,组合是一个很好的选择(即使在允许多重继承的系统中)。并非总是如此,但经常。

如果您需要为ab的A-ness或B-ness添加功能,这些功能也可以访问另一个方面,您可以使用闭包来实现。例如,如果您将对象传递给期望查看A实例并调用其foo函数的第三方库,并且我们希望在{中执行不同的操作,则可能会出现这种情况{1}}基于foo方面的某些状态。例如:

B

请注意上述模式,因为它为{{1>}构造函数生成的每个实例创建了一个新函数。如果有很多,它可能会成为记忆问题。

此时,我们开始偏离继承链和超级调用,我将在this blog post中更详细地讨论这些内容。

function AB() { var aness, bness; this.aness = aness = new A(); this.bness = bness = new B(); // `foo` returns the `a` property of our composite if // it's been changed; otherwise, it returns the `b` // property of our composite. aness.foo = function() { // We want to use `A`'s normal `foo` unless our // B-ness `b` property is 42 for some reason. if (bness.b === 42) { // Our magic number, handle locally. return "The answer"; } // Not our magic number, let `A` handle it return A.prototype.foo.call(this); }; } var ab = new AB(); 链接到AB

如果您是BA的设计者,那么 可以让A继承B,然后您的B可以由A构造函数创建:

ab

...但这意味着所有 B个对象也是A = function () { this.x = 'x'; }; A.prototype.a = 'a'; B = function () { this.y = 'y'; }; B.prototype = new A(); B.prototype.b = 'b'; ab = new B(); ab.a === 'a'; // true ab.b === 'b'; // true A.prototype.a = 'm'; ab.a === 'm'; // true B.prototype.b = 'n'; ab.b === 'n'; // true 个对象,可能不是您想要的。


偏离主题:我没有在上面添加B s假设他们不在那里的原因(例如,他们已经在代码中声明了你“没有表现出来。”

非主题2 :除非你有充分的理由,否则我总是recommend using named functions而不是匿名的(你分配给A和{{1的功能是匿名的。)

答案 1 :(得分:0)

以下是描述在javascript中实现多重继承的方法的链接:

http://www.polyglotinc.com/AJAXscratch/Class/InterfacesFromScratch.html

看起来很复杂。如上所述,它可能更好/更安全/更容易找到另一种方式。