[英]JavaScript - Special multiple inheritance
说我有以下对象类型:
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;
但是由于两个原因,我不喜欢这种方法:
它使Sizable继承自Positionable
,这意味着,如果我希望另一个类型在不成为Positionable
情况下成为Sizable,我将无法做到;
这意味着Sizable
对象也是Positionnable
,从语义Sizable
并不是很好,因为没有理由将Sizable
对象设为Positionnable
而不是相反。
因此,我首先考虑合并原型,假设我有一个函数void merge( type dst, type src, bool overwrite )
,则在循环中,我将简单地将每个基类原型合并到子类型原型中。 这不会创建一个链(如上所述,这就是我想要的)
但是,这会引起另一个问题:由于我没有使用new,因此不会调用基本构造函数。 所以我想知道,有没有一种方法可以合并构造函数? 例如,如果我可以访问和引用基本构造函数,则可以将每个这些基本构造函数存储在一个数组中,并为子类型构造函数分配一个函数,并依次调用每个这些构造函数。
我该如何使用构造函数呢? 也许还有另一种方法?
谢谢你的帮助 !
由于JavaScript不支持多重继承,因此您必须解析为mixins 。 就像您说的那样,您必须将其中一个原型的方法复制到子原型。
构造函数应在子构造函数内部调用。 这是一个例子:
var Rectangle = function() {
Sizeable.call(this);
Positionnable.call(this);
};
// Rectangle inherits from Sizeable
Rectangle.prototype = Object.create(Sizeable.prototype);
// Mixin Positionnable
merge(Rectangle.prototype, Positionnable.prototype);
// alternatively you could mixin both of the prototypes
另请参阅: 使用Object.create进行继承的好处
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构造函数不期望任何参数。 如果必须将参数传递给它们,则必须在target / child构造函数中显式调用它们。
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.