JavaScript的 - 特别多继承
说我有以下对象类型:JavaScript的 - 特别多继承
var Positionable = function() { };
Positionable.prototype.x = 0;
Positionable.prototype.y = 0;
var Sizable = function() { };
Sizable.prototype.w = 0;
Sizable.prototype.h = 0;
var Fadable = function() { };
Fadable.prototype.a = 0;
我想有一个功能,让我创造条件,从其他几种类型的继承子类型。例如,我可以创建一个类型为Rectangle
,它将继承Positionnable
和Sizable
。
我所能链原型:
var Rectangle = function() { };
Sizable.prototype = new Positionable;
Rectangle.prototype = new Sizable;
但我不喜欢这种方法FO两个原因:
它会导致可调整大小从
Positionable
继承,这意味着,如果我想另一个类型是可变的而不是Positionable
,我做不到;这意味着一个
Sizable
对象也是Positionnable
,其语义上是不好的,因为没有理由为Sizable
对象是Positionnable
,而不是其他方式。
所以,我首先想到的关于合并的原型,假设我有一个函数void merge(type dst, type src, bool overwrite)
,回路我会简单地合并每个基类的原型到子类的原型。这不会创建一个链(这是我想如上所述)
但是这会导致另一个问题:因为我没有使用新的基础构造函数不会被调用。所以我想知道,有没有办法也可以合并构造函数?例如,如果我可以访问和引用基础构造函数,我可以将这些基础构造函数存储在一个数组中,并为子类型构造函数分配一个函数来调用每个构造函数。
我怎么能这样做与构造函数?或者,也许有另一种方式?
感谢您的帮助!
由于JavaScript不支持多重继承,因此您必须解析为mixins。这就像你说的,你必须将其中一个原型的方法复制到子原型。
应该在子构造函数中调用构造函数。这里有一个例子:
参见:Benefits of using `Object.create` for inheritance
function mixin(Target) {
var args = arguments;
// merge prototypes
for(var i = 1; i < args.length; i++) {
merge(Target.prototype, args[i].prototype);
}
// a new constructor function which calls all
// the passed constructor functions
var F = function() {
var instance = Target.apply(this, arguments);
for (var i = 1; i < args.length; i++) {
args[i].call(instance);
}
return instance;
};
F.prototype = Target.prototype;
return F;
};
// usage
Rectangle = mixin(Rectangle, Sizeable, Positionnable);
这工作一个假设下:在mixin的构造函数不要指望任何参数。如果您必须将参数传递给它们,则必须在目标/子构造函数中显式调用它们。
if you use Object.Create(),you have to think about browser compatibility. you can write
a function to resolve the issue.eg:
function multipleinheritPrototype() {
if (arguments.length == 0) {
return;
}
var args = arguments;
var sub = args[0];
var constructor = sub.prototype.constructor;
if (!Object.create) {
Object.prototype.create = function (obj) {
function f() {
}
f.prototype = obj;
return new f();
};
}
var base;
for (var i = 1; i < args.length; i++) {
base = Object.create(args[i].prototype);
for (var attr in base) {
sub.prototype[attr] = base[attr];
}
}
sub.prototype.constructor = constructor;
}
you can such so use it.
multipleinheritPrototype(Rectangle, Sizeable, Positionnable);
如果您仅将它用于第一个参数,那么'Object.create'很容易变形:https://developer.mozilla.org/en-US/文档/网络/的JavaScript /参考/ Global_Objects /对象/创建#填充工具。顺便说一句,你必须将该函数分配给Object.create而不是Object.prototype.create。 –
谢谢。看起来也很有趣,我会试试看。 – Virus721
感谢您的帮助。如果没有其他方式,我可能会这么做,但是我看到的“问题”是我必须做两件事而不是一件事:1)调用子构造函数中的父构造函数,2)合并原型。我想在一个函数中完成所有这些工作,但为了做到这一点,我需要有可能访问和分配构造函数。可能吗 ?谢谢。 – Virus721
@ Virus721:您应该始终在子构造函数中调用父构造函数,因为这是所有实例特定的初始化发生的地方。当然,如果父构造函数不做任何事情(即它们不包含任何代码),那么您不必调用它们。如果您可以重新定义“矩形”功能,则可以自动完成整个过程。我会举一个例子。 –
Dojo的mixin功能让我想起了这个问题,并自动处理构造函数链。根据您的需求和要求,我建议您考虑一下。 – Phix