如何为JS Date类实现支持参数的moment.js格式化Polyfill?
为Date.prototype实现带参数的moment风格格式化方法遇到的问题
问题描述
我正尝试为JavaScript的Date类实现基于moment.js格式化的Polyfill。当前我的代码如下:
Object.defineProperty( Date.prototype, 'toDateFormat', { get: function(format) { return moment(this).format(format || 'YYYY-MM-DD'); } });
预期效果是用户调用mydate.toDateFormat('MMM YYYY')时能得到'May 2018'。但问题在于getter中的format参数始终为undefined,我意识到无法向Object.defineProperty的getter传递参数,目前程序只能使用默认的'YYYY-MM-DD'格式。请问是否有办法实现该需求?
解决方案
你完全找对了问题的根源:getter函数是无法接收参数的——它的作用是当你访问对象属性时触发,没有参数传递的机制。你现在的写法把toDateFormat定义成了一个getter,所以当你尝试像函数一样传参调用时,本质上是先执行getter(此时没有参数,format自然是undefined),然后试图把getter返回的字符串当成函数调用,这显然不符合预期。
正确的做法是把toDateFormat定义成一个原型方法,也就是给Object.defineProperty的value属性赋值一个可接收参数的函数:
Object.defineProperty(Date.prototype, 'toDateFormat', { value: function(format) { return moment(this).format(format || 'YYYY-MM-DD'); }, // 可选配置:对齐原生Date方法的默认行为 writable: true, enumerable: false, configurable: true });
这样修改后,当你调用mydate.toDateFormat('MMM YYYY')时,format参数就能正确接收传入的值,moment.js也会按照指定格式返回格式化后的日期字符串了。
额外说明:
enumerable: false可以避免这个方法在for...in循环中被枚举出来,这和原生Date类的方法行为一致- 如果不想让这个方法被意外覆盖,可以把
writable设为false configurable: true允许后续通过delete或者重新定义来修改这个方法,根据你的需求调整即可
内容的提问来源于stack exchange,提问作者Gerrie van Wyk
相关产品推荐
相关产品推荐

