gpt4 book ai didi

javascript:创建一个对象,该对象继承自多个构造函数的原型(prototype)

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:38:03 25 4
gpt4 key购买 nike

假设我有两个构造函数:

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

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

我如何创建一个对象 ab 继承两者的原型(prototype)?所以下面的例子将起作用:

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

谢谢

最佳答案

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

继承一个,复制另一个

单个对象 的属性而言,您所能做的就是从其中一个原型(prototype)继承并复制另一个原型(prototype)的属性。显然这不是您想要的,因为您没有复制属性的实时引用方面,但就在单个对象上拥有这些属性而言,这是您所能做的全部。

组成

另一种选择是组合:

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 函数,并且我们想要根据 B 方面的某些状态在 foo 中做一些不同的事情。例如:

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 构造函数生成的每个实例 创建了一个新函数。如果有很多,它可能会成为内存问题。

在这一点上,我们开始误入继承链和 super 调用,我在 this blog post 中对此进行了更详细的讨论。 .

链接BA

如果您是 AB 的设计者,可能 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 对象也是A 对象,这可能不是您想要的。


题外话:我没有在上面添加 var 是因为假设它们不存在是有原因的(例如,它们已经声明在你没有显示的代码中)。

题外话2:除非你有充分的理由,否则我总是recommend using named functions而不是匿名函数(您分配给 AB 的函数是匿名的)。

关于javascript:创建一个对象,该对象继承自多个构造函数的原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4245289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com