使用jquery的extend进行函数对象继承

时间:2013-07-30 22:44:50

标签: javascript jquery

我尝试使用jquery扩展模拟继承,但据我测试,它仅适用于对象。

我想要完成的是:

var baseDefinition = function() {
    var self = this;

    self.calc1 =  function() {
        return "something1";
    }

    self.calc2 =  function() {
        return "something2";
    } 

    self.myObject = {
        propA = 100;
        propB = 200;
    };
}

var derivedDefinition = function() {
    var self = this;

    self.calc2 =  function() {
        return "something different from base";
    }

    self.myObject = {
        propB  = 400;
    };            
}

var instance = $.extend(true, {}, baseDefinition, derivedDefinition);

所以我希望从基本定义创建一个新实例,其中派生定义将应用于基本定义,但两个定义都不会被触及"。有可能吗?

我希望避免使用任何原型,因此我想调用instance.calc1或instance.calc2而不知道它是否被覆盖。

修改

在我的例子中,我没有包含任何对象属性,这导致我使用jquery的扩展函数。虽然这两个答案都解决了内部函数和继承问题,但它并没有(显然)合并像extend这样的对象属性。作为一种可能的解决方案,我想在创建实例后循环遍历实例的属性并应用jquery扩展它们。虽然这对我来说效率低下,但我不知道你是否可以就另一种行动方案向我提出建议。

2 个答案:

答案 0 :(得分:4)

JQuery扩展不会创建继承层次结构,因此在扩展后对基本定义所做的更改不会反映在派生定义中。以下是如何使用Javascript原型继承以一种确实反映继承层次结构中的后续更改的方式扩展基本定义:

var baseDefinition = function() {};

baseDefinition.prototype.calc1 =  function() {
    return "something1";
};

baseDefinition.prototype.calc2 =  function() {
    return "something2";
};   


var derivedDefinition = function() {};

derivedDefinition.prototype = Object.create(baseDefinition.prototype);

derivedDefinition.prototype.calc2 =  function() {
    return "something different from base";
};

var instance = new derivedDefinition();
instance.calc1();  // something1
instance.calc2();  // something different from base

答案 1 :(得分:1)

$.extend仅适用于已存在的对象,而不适用于将在(远?)未来实例化对象的函数:

var instance = $.extend(true, {}, new baseDefinition(), new derivedDefinition());

但是,您当然可以设计一个适用于构造函数并返回函数的extend函数:

function extendConstr() {
    var fns = arguments;
    return function newConstr(){
        var self = {};
        for (var i=0; i<fns.length; i++)
            fns[i].apply(self, arguments);
        return self;
    }
}

var extendedFunction = extendConstr(baseDefinition, derivedDefinition);

var instance = extendedFunction();
console.log(instance); // has `calc1` and overwritten `calc2`

顺便说一句,没有extend函数你可以在派生的构造函数中手动完成:

function derivedDefinition() {
    baseDefinition.call(this/*, arguments */);

    this.calc2 =  function() {
        return "something different from base";
    }
}
console.log(new derivedDefinition) // has a `calc1` as well