如何在不影响原始函数的情况下扩展(使用新名称)javascript 中的静态函数?

Zak*_*nry 5 javascript oop momentjs

我在解决如何扩展静态函数 (momentjs) 以便我可以覆盖这些方法但不更改原始函数时遇到问题。

需要明确的是,我知道如何扩展moment的实例来覆盖函数,但我想直接扩展库,这样我就moment可以像 momentjs 一样使用自己的命名实例。

例如,我希望能够执行以下操作

extendedMoment().customFunction() //do something custom
extendedMoment().toString() //use customised toString() method
extendedMoment().format() //use the original momentjs method
Run Code Online (Sandbox Code Playgroud)

我已经尝试了一些复制原型等选项,但是编辑新extendedMoment功能的原型似乎会影响原始功能。

更新:@PatrickRoberts 在下面回答

Pat*_*rts 4

在深入研究源代码之后,您实际上无法直接扩展该库,因为有几个未公开的作用域函数,它们moment()实际上是构造函数的包装器的包装器的包装器的包装器的包装器。因此,通过重用相同的扩展原型而不是在工厂扩展内分配作用域函数,您可以做到以下几点:

function extendedMoment () {
  return Object.setPrototypeOf(moment(), extendedMoment.prototype);
}

Object.setPrototypeOf(extendedMoment.prototype, moment.prototype);
Object.setPrototypeOf(extendedMoment, moment);

extendedMoment.prototype.toString = function toString () {
  return this.format('YYYY-MM-DD');
};

console.log("Original: " + moment().toString());
console.log("Extended: " + extendedMoment().toString());
Run Code Online (Sandbox Code Playgroud)
<script src="http://momentjs.com/downloads/moment.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

它的工作方式是用工厂扩展内部替换实例的原型(最初是Moment.prototype) ,为 的所有实例重用相同的函数。extendedMoment.prototypetoStringextendedMoment

编辑

我发现自己使用了“构造函数”这个术语,所以extendedMoment我纠正了自己。它实际上是一个工厂扩展,因为正如 @ZakHenry 指出的那样,它是一个静态函数。对用词不当表示歉意。