我有以下代码:

function Rune(){
    this.subSpells = [];
}
function Modifier(){
    this.type = "modifier";
}
Modifier.prototype = new Rune();

function RuneFactory(effect, inheritsFrom, initialValue){
    var toReturn = function(){};
    toReturn.prototype = new inheritsFrom();
    toReturn.prototype.subSpells[effect] = initialValue;
    return toReturn;
}

Duration = RuneFactory("duration", Modifier, 1);
Quicken = RuneFactory("quicken", Modifier, 1);

x = new Duration();
y = new Quicken();

x.subSpells.duration和x.subSpells.quicken都等于1。与y相同。
我希望x.subSpells.quicken和y.subSpells.duration未定义。

如果对“持续时间”和“加快”定义执行以下操作,则会得到所需的行为。
Duration = RuneFactory("duration", Rune, 1);
Quicken = RuneFactory("quicken", Rune, 1);

我认为双重继承存在问题。谁能告诉我如何更改我的RuneFactory代码,使其可用于双重继承和/或解释发生了什么问题?如果可能的话,我想避免使用框架。

谢谢!

最佳答案

在修饰符函数Rune.apply(this, arguments);中添加以下行,因为subSpells在原型(prototype)级别定义,所以符文的所有实例都引用同一对象。
并且,将subSpells的类型从数组更改为对象。

所述,警告如果使用寄生组合继承模式,会更好。

“我认为双重继承有问题”-不!

最初,没有双重继承的问题,与Modifier构造函数有相同的问题,您的实例引用了相同的subSpells对象(在您的情况下为Array。请阅读有关Primitive value vs Reference valueReferences and Values的内容,其有关.NET的知识,但基本原理相同编程)。

How does JavaScript .prototype work?

jsFiddle

function inheritPrototype(subType, superType) {
    var prototype = Object.create(superType.prototype, {
        constructor: {
            value: subType,
            enumerable: true
        }
    });

    subType.prototype = prototype;
}

function Rune() {
    this.subSpells = {};
}

function Modifier() {
    Rune.apply(this, arguments);
    this.type = "modifier";
}

inheritPrototype(Modifier, Rune);

function RuneFactory(effect, inheritsFrom, initialValue) {
    function toReturn() {
        inheritsFrom.apply(this, arguments); // you should bind this
        this.subSpells[effect] = initialValue;
    }
    inheritPrototype(toReturn, inheritsFrom);
    return toReturn;
}

Duration = RuneFactory("duration", Modifier, 1);
Quicken = RuneFactory("quicken", Modifier, 1);

x = new Duration();
y = new Quicken();

console.log(x.subSpells.duration); // 1
console.log(x.subSpells.quicken); // undefined

console.log(y.subSpells.duration); // undefined
console.log(y.subSpells.quicken); // 1

07-24 17:18