2012-01-19 100 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