【问题标题】:javascript inheritance from multiple objectsjavascript从多个对象继承
【发布时间】:2011-06-12 09:33:46
【问题描述】:

我不太熟悉 javascript 继承,我试图让一个对象从另一个对象继承,并定义它自己的方法:

function Foo() {}
Foo.prototype = {
    getColor: function () {return this.color;},
};
function FooB() {}
FooB.prototype = new Foo();
FooB.prototype = {
    /* other methods here */
};

var x = new FooB().getColor();

但是,第二个会覆盖第一个 (FooB.prototype = new Foo() is cancelled out)。有什么办法可以解决这个问题,还是我走错了方向?

在此先感谢,对于任何不好的术语,我们深表歉意。

【问题讨论】:

    标签: javascript oop multiple-inheritance prototypal-inheritance


    【解决方案1】:

    每个对象只能有一个原型,所以如果你想在继承(复制)它后添加到原型中,你必须扩展它而不是分配一个新的原型。示例:

    function Foo() {}
    
    Foo.prototype = {
        x: function(){ alert('x'); },
        y: function(){ alert('y'); }
    };
    
    function Foo2() {}
    
    Foo2.prototype = new Foo();
    Foo2.prototype.z = function() { alert('z'); };
    
    var a = new Foo();
    a.x();
    a.y();
    var b = new Foo2();
    b.x();
    b.y();
    b.z();
    

    【讨论】:

    • 有没有办法用另一个对象扩展原型而不覆盖它?
    • @digitalFresh:不,没有办法连接对象,因此您必须将每个属性从一个对象复制到另一个对象。然而,这可以通过循环来完成。例如,jQuery.extend 方法就是这样做的。
    • @digitalFresh - 你当然可以像@Guffa 写的那样扩展它。有关更多详细信息,请参阅我的答案(不使用 jQuery)。
    【解决方案2】:

    一种解决方案是:

    function FooB() {}
    var p = new Foo();
    p.methodA = function(){...}
    p.methodB = function(){...}
    p.methodC = function(){...}
    ...
    
    FooB.prototype = p;
    

    更新:关于使用现有对象进行扩展。您始终可以将一个对象的现有属性复制到另一个对象:

    FooB.prototype = new Foo();
    var proto = {
         /*...*/
    };
    
    for(var prop in proto) {
        FooB.prototype[prop] = proto[prop];
    }
    

    只要proto 是一个“普通”对象(即不从另一个对象继承)就可以了。否则,您可能希望添加 if(proto.hasOwnProperty(prop)) 以仅添加非继承属性。

    【讨论】:

    • proto 可以是“普通”对象,但如果第三方脚本扩充了Object.prototype,您最终会将这些值复制到FooB.prototype
    【解决方案3】:

    您可以使用extend 函数将新成员复制到原型对象。

    function FooB() {}
    FooB.prototype = new FooA();
    
    extend(FooB.prototype, {
        /* other methods here */
    });
    

    扩展

    /**
     * Copies members from an object to another object.
     * @param {Object} target the object to be copied onto
     * @param {Object} source the object to copy from
     * @param {Boolean} deep  whether the copy is deep or shallow
     */
    function extend(target, source, deep) {
        for (var i in source) {
            if (deep || Object.hasOwnProperty.call(source, i)) {
                target[i] = source[i];
            }
        }
        return target;
    }
    

    【讨论】:

      猜你喜欢
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      相关资源
      最近更新 更多