【问题标题】:function object inheritance using jquery's extend使用jquery的扩展函数对象继承
【发布时间】:2013-07-30 22:44:49
【问题描述】:

我正在尝试使用 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 的扩展后正在考虑。虽然这对我来说似乎效率低下,但我不知道您是否可以就其他行动方案给我建议。

【问题讨论】:

  • $.extend() 只用另一个对象的内容更新一个对象中的键。如果链中的第一个对象是{},显然最终结果不会是函数。只需使用显式命名空间对象或常规 JS OO 功能即可。
  • 你是怎么调用这些函数的?
  • @millimoose 我理解你对“命名空间”对象的意思,但这会覆盖整个函数“类”而不是它的覆盖。如果我错了,请告诉我。对于 JS OO,您的意思是使用原型?
  • @DevRios 是的,我的意思是 JS 中的机制已经提供了继承,而不是尝试自己滚动。

标签: javascript jquery


【解决方案1】:

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

【讨论】:

  • 这是一个很好的问题,它提出了一个非常重要的话题“这是您如何扩展基本定义的方式,以反映以后的继承层次结构的变化”我会尽快提出这个问题有足够的声誉,但在这种特殊情况下,我想要一个冻结的时间实例。
  • 非常好,但在 ie developer.mozilla.org/en-US/docs/Web/JavaScript/…
【解决方案2】:

$.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

【讨论】:

  • 我刚刚在 jsfiddle 中测试了你的方法,它似乎工作得很好。我将使用我的真实定义进行更彻底的测试。
  • 不要只是测试,尝试理解它:-) This doc 可能会帮助你...
  • 我认识 Call and Apply 先生已经有几年了,但现在我明白你在做什么了,实际上非常聪明。
  • 如果您不介意阅读我的问题编辑,我将不胜感激
猜你喜欢
  • 1970-01-01
  • 2014-11-28
  • 2023-04-11
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多