1

假设我有以下对象类型:

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,这意味着如果我想要另一种类型为 Sizable 而不是Positionable,我不能这样做;

  • 它意味着一个Sizable对象也是Positionnable,这在语义上并不好,因为没有理由让一个Sizable对象存在Positionnable而不是相反。

所以我首先考虑合并原型,假设我有一个函数void merge( type dst, type src, bool overwrite ),在循环中我会简单地将每个基类原型合并到子类型原型中。这不会创建一个链(这就是我想要的,如上所述)

但这会导致另一个问题:因为我没有使用 new,所以不会调用基本构造函数。所以我想知道,有没有办法也合并构造函数?例如,如果我可以访问和引用基本构造函数,我可以将这些基本构造函数中的每一个存储在一个数组中,并为子类型构造函数分配一个连续调用这些构造函数的函数。

我怎么能用构造函数做到这一点?或者也许还有另一种方式?

谢谢你的帮助 !

4

2 回答 2

2

由于 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 构造函数不期望任何参数。如果必须向它们传递参数,则必须在目标/子构造函数中显式调用它们。

于 2013-08-29T05:04:29.207 回答
0
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);
于 2013-08-29T06:42:53.990 回答