Как вызвать исходный метод после его переопределения

#javascript

#javascript

Вопрос:

В Javascript, когда я переопределяю Date.prototype.toString функцию, вывод Date() функции не изменяется, и функция сохраняет свой исходный код.

 console.log(Date());
console.log(new Date().toString());

Date.prototype.toString = function() { return this.toISOString() }

console.log(Date());
console.log(new Date().toString());
 

«Вт, 26 января 2021 года, 17:30:33 GMT-0500 (восточное стандартное время)»

«Вт, 26 января 2021 года, 17:30:33 GMT-0500 (восточное стандартное время)»

«Вт, 26 января 2021 года, 17:30:33 GMT-0500 (восточное стандартное время)»

«2021-01-26T22:30:33.821Z»

Протестируйте его здесь.


Однако, когда мне нужно было использовать более сложное переопределение Date класса — в моем случае изменение шага синхронизации на 5-секундный интервал — после переопределения Date.prototype.toString функции выходные Date() данные также изменяются. Поскольку функциональность Date() функции не должна меняться, это нежелательное и нежелательное изменение.

 console.log(Date());
console.log(new Date().toString());

(function() {
  let ___now = Date.now;
  Date = new Proxy(Date, {
    construct(target, args) {
      if (args[0] === undefined) args[0] = this.adjust()
      let date = new target(...args);
      return date;
    },
    apply(target, thisArg, argumentList) {
      return new Date(this.adjust()).toString();
    },
    adjust() {
      return 5000 * Math.floor(___now() / 5000);
    }
  });
})();
Date.prototype.toString = function() { return this.toISOString() }

console.log(Date());
console.log(new Date().toString());
 

«Вт, 26 января 2021 года, 17:30:35 GMT-0500 (восточное стандартное время)»

«Вт, 26 января 2021 года, 17:30:35 GMT-0500 (восточное стандартное время)»

«2021-01-26T22:30:35.000Z» «2021-01-26T22:30:35.000Z»

«2021-01-26T22:30:35.000Z» «2021-01-26T22:30:35.000Z»

Протестируйте его здесь.


Как я должен изменить приведенный выше код, чтобы заставить Date() функцию использовать исходную toString() функцию, даже если она переопределена? Изменение toString() должно применяться только тогда, когда оно вызывается явно, как показано в примерах выше.

Ответ №1:

Для вас должно сработать следующее:

 console.log(Date());
console.log(new Date().toString());

(function() {
  const ___now = Date.now;
  const ___toString = Date.prototype.toString;
  Date = new Proxy(Date, {
    construct(target, args) {
      if (args[0] === undefined) args[0] = this.adjust()
      let date = new target(...args);
      return date;
    },
    apply(target, thisArg, argumentList) {
      return ___toString.bind(new Date()).call();
    },
    adjust() {
      return 5000 * Math.floor(___now() / 5000);
    }
  });
})();

Date.prototype.toString = function() { return this.toISOString() }

console.log(Date());
console.log(new Date().toString());