一个(有点模糊)Javascript继承问题

时间:2010-07-22 23:22:16

标签: javascript oop inheritance prototype function

我一直在尝试使用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函数调用时:

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

但是当你首先实例化一个Date实例时:

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

我很遗憾,因为我相信你能说出来,但希望你能明白这一点。我的问题是:第一个tomorrow()函数与Date对象的关系是什么?究竟是什么附属于什么?

假设您使用的是普通函数,而不是构造函数。是否可以从原始函数中调用增广函数?

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

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 个答案:

答案 0 :(得分:2)

Date是window对象的function(),并且您正在为该函数附加另一个函数。很奇怪呃?

试试这个:

function a()
{
    return 10;
}

a.e = "oO";

typeof(a);
typeof(a.e);

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

function a () {
    return arguments.callee.e;
}

a.e = "Oo"

a();

答案 1 :(得分:0)

由于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);