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());

"Tue Jan 26 2021 17:30:33 GMT-0500 (Eastern Standard Time)"

"Tue Jan 26 2021 17:30:33 GMT-0500 (Eastern Standard Time)"

"Tue Jan 26 2021 17:30:33 GMT-0500 (Eastern Standard Time)"

"2021-01-26T22:30:33.821Z"

测试一下 here .


但是,当我需要使用更复杂的 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());

"Tue Jan 26 2021 17:30:35 GMT-0500 (Eastern Standard Time)"

"Tue Jan 26 2021 17:30:35 GMT-0500 (Eastern Standard Time)"

"2021-01-26T22:30:35.000Z" "2021-01-26T22:30:35.000Z"

"2021-01-26T22:30:35.000Z" "2021-01-26T22:30:35.000Z"

测试一下 here .


我应该如何修改上面的代码以强制 Date() 函数使用原始的 toString() 函数,即使它被覆盖了? toString() 的更改应该仅在显式调用时才适用,如上例所示。

最佳答案

以下应该适合您:

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());

关于javascript - 如何在覆盖后调用原始方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65910344/

相关文章:

javascript - Promise.resolve() 在 setTimeout() 中返回一个奇怪的结果

javascript - 将值从 javascript 插入数据库

javascript - 如何在不知道 javascript 中使用 JSON 的特定键的情况下获取属性值

javascript - 使用 javascript 更改标签文本并从后面的代码中读取它

javascript - 单击事件撤消

javascript - !!~(不是 not not tilde/bang bang tilde)如何改变 'contains/included' 数组方法调用的结果?

javascript - 访问不在作用域内的函数

javascript - 使用 Greensock 制作雪佛龙动画

Javascript 对象编程和对象表示

javascript - 将对象数据传递给 jQuery.post 后继函数