繁体   English   中英

JavaScript-特殊多重继承

[英]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类型,该类型将从PositionnableSizable继承。

我可以链接原型:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM