我一直在尝试使用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
答案 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);