2012-01-19 59 views
4

我正在开发一个对当前日期很敏感的浏览器应用程序。重写Javascript日期构造函数?

在我的应用程序代码中,我调用new Date并根据当前时间执行计算并相应地呈现视图。

为了测试我的应用程序对于不同的潜在日历日,我将不得不不断地将我的系统时钟更改为过去或未来,这是一种烦恼,可能对我的电脑并不健康。

所以,纯粹是出于测试目的(我将永远不会在生产中使用此代码),我决定重写内置Date构造函数通过在控制台这样做:

// create a date object for this Friday: 
var d = new Date(2012, 0, 20) 
//override Date constructor so all newly constructed dates return this Friday 
Date = function(){return d} 

在这个假设一点,我想这一点,得到了奇怪的结果:

var now = new Date 
Sat Apr 07 2012 00:00:00 GMT-0400 (EDT) 

now = new Date 
Tue Jul 10 2012 00:00:00 GMT-0400 (EDT) 

now = new Date 
Wed Jul 09 2014 00:00:00 GMT-0400 (EDT) 

now = new Date 
Wed Jun 07 2023 00:00:00 GMT-0400 (EDT) 

...等等....

我的问题是,究竟是怎么回事?

如果我覆盖构造函数以返回一个静态日期,为什么它给不相关的和不断递增的日期?

另外,有没有一种有效的方法,我可以重写Date构造函数来在将来返回一个静态日期,而无需经过我的代码中的所有日期实例化调用并修改输出?

在此先感谢。

编辑:

我想我的代码在一个新的窗口,它的工作如预期。

它似乎是罪魁祸首是调用其“刷新”方法的jQuery UI datepicker插件。当我禁用它的调用时,日期覆盖正常工作,但只要我使用日期选择器,就会发生上述奇怪的行为。

不知道为什么这个流行的插件会以某种方式影响这样的全局。如果有人有任何想法,请告诉我。

对不起,以前没有找出真正的罪魁祸首。

+0

我无法重现您所看到的递增行为。你在什么浏览器/环境? –

+0

我使用的是OSX 10.7.2上的Chrome 17。 – Dan

+0

我写了一个库,允许覆盖Date构造函数并设置时间和时区以用于测试目的:https://github.com/plaa/TimeShift-js – Sampo

回答

6

我测试你的代码:

// create a date object for this Friday: 
var d = new Date(2012, 0, 20); 
//override Date constructor so all newly constructed dates return this Friday 
Date = function(){return d;}; 

var now = new Date() 
console.log(now); 

now = new Date() 
console.log(now); 

now = new Date() 
console.log(now); 

now = new Date() 
console.log(now); 

而结果????为什么如此不同?

Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)} 
Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)} 
Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)} 
Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)} 

编辑:

我看到,每当你用日期选取器进行交互,行为变的不同。尝试另一个测试,改变now是一样的东西与日期选取器进行交互:

// create a date object for this Friday: 
var d = new Date(2012, 0, 20); 
//override Date constructor so all newly constructed dates return this Friday 
Date = function(){return d;}; 

var now = new Date(); 
var another = new Date(); 
console.log(now); 

another.setDate(13); 

now = new Date() 
console.log(now); 

,其结果是:

Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)} 
Date {Fri Jan 13 2012 00:00:00 GMT+0700 (SE Asia Standard Time)} 

那么,究竟错在何处? 您已经

Date = function(){return d;}; // after construction, all date will be d (2012-01-20) 
var now = new Date(); // you instantiate a date, but actually now variable is d (2012-01-20) 
var another = new Date(); // you instantiate a date, but another is still d (2012-01-20) 
another.setDate(13); // change another date to 13 is to change now to 13 (because now and another is still one d) 

now = new Date() // still d 
console.log(now); // print out now (2012-01-13) 

所以覆盖核心日期的功能,你这是导致所有日期使用相同(只有一个)实例的功能,这是d(2012-01-20)覆盖核心日期的功能。更改任何日期影响他人。

+0

谢谢,请参阅我的上述编辑以了解导致行为的原因。当我拥有足够的代表时,我会赞成。 – Dan

+0

我刚刚编辑了答案,请通过 –

+0

看到啊我看到了。所有新建的日期共享同一个对象,因此对其中一个的修改会影响其他对象我认为我的目的解决方案是从构造函数提供一个克隆的对象。谢谢你的帮助! – Dan

3

给这个镜头。

var d = new Date(2012, 0, 20); 
// undefine date so that it will only return what your function returns 
Date = undefined; 
Date = function(){return d;} 

修改原型指向您的对象应该做的伎俩。

我相信你之前经历过的奇怪行为是私人的Date拥有一些时间概念,并且由于原型指向了内部时钟,所以你得到的是随机时间。

+0

感谢您的建议,但那不是实际的问题。请参阅我的上述编辑以了解导致行为的原因。当我拥有足够的代表时,我会赞成。 – Dan

+0

@ amchang87:在任何情况下,行'Date = undefined;'在你的代码中没有任何意义。 –

7

我也遇到了这个问题,并最终为此写了一个模块。或许是为别人有用:

Github上:https://github.com/schickling/timemachine

timemachine.config({ 
    dateString: 'December 25, 1991 13:12:59' 
}); 

console.log(new Date()); // December 25, 1991 13:12:59