说我有两个构造函数:
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
由于
答案 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
如果您是B
和A
的设计者,那么 可以让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
看起来很复杂。如上所述,它可能更好/更安全/更容易找到另一种方式。