Переопределить конструктор Javascript Date? - PullRequest
9 голосов
/ 19 января 2012

Я занимаюсь разработкой приложения для браузера, чувствительного к текущей дате.

Во всем коде моего приложения я вызываю 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 constructor для возврата статической даты в будущем без необходимости проходить через все вызовы инстанцирования даты в моем коде и изменять вывод?

Заранее спасибо.

РЕДАКТИРОВАТЬ:

Я попробовал свой код в новом окне, и он работал как ожидалось.

Кажется, виновником был плагин dateQicker пользовательского интерфейса jQuery, который вызывал свой метод "refresh".Когда я отключаю его вызов, переопределение даты работает нормально, но как только я использую средство выбора даты, происходит странное поведение, описанное выше.

Не знаю, почему этот популярный плагин каким-то образом повлияет на что-то глобальное, подобное этому.Если у кого-то есть идеи, дайте мне знать.

Извините, что не выяснил истинного виновника ранее.

Ответы [ 5 ]

10 голосов
/ 28 сентября 2013

Я также столкнулся с этой проблемой и в итоге написал модуль для этого.Возможно, это кому-нибудь пригодится:

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
9 голосов
/ 19 января 2012

Я проверил ваш код:

// 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)}

РЕДАКТИРОВАТЬ:

Я видел, что всякий раз, когда вы взаимодействуете с Date Picker, поведение меняется.Попробуйте другой тест, измените 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 на

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)

Итак, вы переопределяете основную функцию Date функцией, которая заставляет все даты использовать один и тот же (только один) экземпляр, который d (2012-01-20).Изменение любых дат влияет на другие.

4 голосов
/ 19 января 2012

Дайте этому шанс.

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;}

Изменение прототипа так, чтобы оно указывало на ваш объект, должно помочь.

Я считаю, что странное поведение, которое вы испытывали ранее, заключалось в том, что в частном порядке Дата хранит некоторое представление о времени, и, поскольку прототип указывает на эти внутренние часы, вы получаете случайные времена.

2 голосов
/ 10 октября 2018

Это работает для меня.

I.E как вернуть время процесса 1 минуту назад

Date = class extends Date{
     constructor(options) {
       if (options) {
         super(options);
       } else {
         super(Date.now() - 1000 * 60);
       }
     }
   };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...