I'm having trouble working out how to extend a static function (momentjs) so that I can override the methods, but without altering the original function.
To be clear I know how to extend an instance of moment to override the functions, but I want to extend the library directly so I get my own named instance of moment
that I can use in the same way as momentjs.
As an example, I'd like to be able to do the following
extendedMoment().customFunction() //do something custom
extendedMoment().toString() //use customised toString() method
extendedMoment().format() //use the original momentjs method
I've tried a few options with copying the prototype etc, but editing the prototype of the new extendedMoment
function seems to affect the original.
Update: answered below by @PatrickRoberts
After some digging into the source, you can't really directly extend the library because there are several scoped functions which are not exposed, and moment()
is actually a wrapper of a wrapper of a wrapper of a wrapper of the constructor. So here's about the best you can do by reusing the same extended prototype rather than assigning scoped functions inside the factory extension:
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());
<script src="http://momentjs.com/downloads/moment.min.js"></script>
The way this works is it replaces the instance's prototype (which is initially Moment.prototype
) with extendedMoment.prototype
inside the factory extension, reusing the same toString
function for all instances of extendedMoment
.
EDIT
I caught myself using the term "constructor" for extendedMoment
so I corrected myself. It is actually a factory extension, since it is a static function as @ZakHenry pointed out. Apologies for the misnomer.