Date constructor monkey patch

僤鯓⒐⒋嵵緔 提交于 2019-12-13 18:26:16

问题


I'm trying to monkey patch a javascript Date constructor. I have the following code:

var __Date = window.Date;
window.Date = function(){
    __Date.apply(this, Array.prototype.slice.call(arguments));
};
window.Date.prototype = __Date.prototype;

As far as I know the javascript constructor (when called) does three things:

  1. It creates a new object that the this points to when the constructor function is executed
  2. It sets up this object to delegate to this constructor's prototype.
  3. It executes the constructor function in the context of this newly created object.

Ad.1 is accomplished automatically by the way that the new Date function will be called (new Date())

Ad.2 if accomplished by setting my new Date.prototype to be the original Date.prototype.

Ad.3 is accomplished by calling the original Date function in the context of the newly created object with the same paramters that are passed to "my" Date function.

Somehow it does not work. When i call e.g. new Date().getTime() i get an error saying that TypeError: this is not a Date object.

Why doesn't it work? Even this code:

new Date() instanceof __Date

returns true so by setting the same prototypes i fooled the instanceof operator.

PS. the whole point of this is that I want to check the arguments passed to the Date constructor and alter them when a certain condition is met.


回答1:


Thanks to the link provided by @elclanrs I have come up with a working solution:

var __Date = window.Date;
window.Date = function f(){
    var args = Array.prototype.slice.call(arguments);
    // Date constructor monkey-patch to support date parsing from strings like
    // yyyy-mm-dd hh:mm:ss.mmm
    // yyyy-mm-dd hh:mm:ss
    // yyyy-mm-dd
    if(typeof args[0] === "string" && /^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2}(\.\d{3})?)?$/.test(args[0])){
        args[0] = args[0].replace(/-/g, '/').replace(/\.\d{3}$/, '');
    }
    args.unshift(window);
    if(this instanceof f)
        return new (Function.prototype.bind.apply(__Date, args));
    else
        return __Date.apply(window, args);
};
// define original Date's static properties parse and UTC and the prototype
window.Date.parse = __Date.parse;
window.Date.UTC = __Date.UTC;
window.Date.prototype = __Date.prototype;

Question still remains: why my first attempt didn't work?



来源:https://stackoverflow.com/questions/22400161/date-constructor-monkey-patch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!