代码之家  ›  专栏  ›  技术社区  ›  Adam Lassek

一个(有些模糊的)javascript继承问题

  •  5
  • Adam Lassek  · 技术社区  · 14 年前

    我一直在尝试用Javascript设计一种模式,它允许我使用看起来像单例函数的函数,这些函数可以被实例函数覆盖。

    下面是一个简单的例子:

    Date.tomorrow = function () {
      return Date.today().add(1).days();
    }
    
    (function(p) {
    
      p.tomorrow = function() {
        var date = this.clone().clearTime();
        return date.equals(Date.tomorrow());
      }
    
    })(Date.prototype);
    

    所以有两个 tomorrow() 功能。直接从日期函数调用时:

    >>> Date.tomorrow()
    =>  Fri Jul 23 2010 00:00:00 GMT-0500 (CST) { _orient=1,  more...}
    

    但是,当您首先实例化日期实例时:

    >>> var date = new Date()
    >>> date.tomorrow()
    =>  false
    

    我会留下很多东西,我相信你能说出来,但希望你明白我的意思。我的问题是:第一个的关系是什么? 明日() 函数到日期对象?它到底跟什么有关?

    假设您使用的是一个不打算成为构造函数的普通函数。是否可以从原始函数内调用增强函数?

    在构造函数函数中,可以这样做:

    this.constructor.functionName();
    

    但是,如果函数没有被用作构造函数,显然 constructor 引用不存在。有没有其他方法来访问这个增强函数?

    这个问题背后的动力来自我为一个项目重新组织JS代码的工作。我们正在实施 Sprockets 系统将我们的源代码拆分成模块,在模块中,我们基本上是在构建一个基本名称空间,而不是将其打包在一个不可读的内联对象定义中。

    我们有一些相当大的事件连线,很好地将它们分割成单独的函数,但是我不想单独调用每个函数;相反,我想要一个超函数一次性调用所有子函数。

    我可以一直创建一个 all() 函数或其他实现此功能的方法,但是从API的角度来看,如果调用一个顶级函数来执行它所附加的所有子函数,它看起来会更干净。


    多亏了弗朗西斯科的回应,我现在对我所想的有了一个有效的实现。这里有一个例子,以防有人好奇。

    var Namespace = {};
    
    var Namespace.wireup = (function () {
    
      return function () {
        var self = arguments.callee;
        self.eventWireup1();
        self.eventWireup2();
      };
    
    })();
    
    (function (W) {
    
      function eventWireup1 () { console.log('first function'); };
      function eventWireup2 () { console.log('second function'); };
    
      $.extend(W, {
        eventWireup1: eventWireup1,
        eventWireup2: eventWireup2
      });
    
    })(Namespace.wireup);
    

    此API的好处在于,您可以执行以下操作:

    >>> Namespace.wireup.eventWireup1();
    =>  first function
    >>> Namespace.wireup.eventWireup2();
    =>  second function
    >>> Namespace.wireup();
    =>  first function
    =>  second function
    
    2 回复  |  直到 9 年前
        1
  •  2
  •   Francisco Soto    14 年前

    日期是window对象的函数(),您正在将另一个函数附加到该函数。奇怪吗?

    试试这个:

    function a()
    {
        return 10;
    }
    
    a.e = "oO";
    
    typeof(a);
    typeof(a.e);
    

    要从内部访问e,可以使用参数中的Callee属性,例如:

    function a () {
        return arguments.callee.e;
    }
    
    a.e = "Oo"
    
    a();
    
        2
  •  0
  •   Adam Lassek    9 年前

    自从 arguments.callee 已经被否决了,我认为我应该用一个例子来更新这个问题,我最终过渡到这个例子,它不仅更正确,而且与严格模式兼容。

    var Namespace = {};
    
    (function () {
      Namespace.wireup = function self () {
        self.eventWireup1();
        self.eventWireup2();
      }
    })();
    
    (function (self) {
      self.eventWireup1 = function () { console.log('first function') }
      self.eventWireup2 = function () { console.log('second function') }
    })(Namespace.wireup);