[removed] override Date.prototype.constructor

前端 未结 4 1732
青春惊慌失措
青春惊慌失措 2020-12-14 12:37

I\'d like to change the behaviour of the standard Date object. Years between 0..99 passed to the constructor should be interpreted as fullYear (no

4条回答
  •  独厮守ぢ
    2020-12-14 12:49

    Piggybacking on Aadit M Shah's native date constructor override - this should be a reply but I don't have enough SO rep for that - as @sakthi mentioned, you'd lose your native Date methods by doing it that way. This sucks a bit because Date methods are non-enumerable, so you have to implement a bit of a hack to clone them.

    First off, I'd recommend not doing it this way unless you have to. In my case, I was working in an application with a bunch of legacy code that was constructing dates using the format "m-d-yyyy", which works in chrome but not safari. I couldn't just do a find/replace in the app, because there were lots of instances where the date strings were being pulled from the service layer or the database. So, I decided to override the Date constructor in the case where there's a datestring argument in "m-d-yyyy" format. I wanted it to be as minimally-invasive as possible, so that it functions as a normal Date otherwise.

    Here are my changes - it should allow you to override date with some changes to the constructor, but everything else the same. You're going to want to change the MyDate constructor before instantiate is called to do whatever you want the constructor to handle. This will happen BEFORE the system Date constructor gets applied.

    var bind = Function.bind;
    var unbind = bind.bind(bind);
    
    function instantiate(constructor, args) {
        return new (unbind(constructor, null).apply(null, args));
    }
    
    Date = function (Date) {
    
        // copy date methods - this is a pain in the butt because they're mostly nonenumerable
        // Get all own props, even nonenumerable ones
        var names = Object.getOwnPropertyNames(Date);
        // Loop through them
        for (var i = 0; i < names.length; i++) {
            // Skip props already in the MyDate object
            if (names[i] in MyDate) continue;
            // Get property description from o
            var desc = Object.getOwnPropertyDescriptor(Date, names[i]);
            // Use it to create property on MyDate
            Object.defineProperty(MyDate, names[i], desc);
        }
    
        return MyDate;
    
        function MyDate() {
            // we only care about modifying the constructor if a datestring is passed in
            if (arguments.length === 1 && typeof (arguments[0]) === 'string') {
                // if you're adding other date transformations, add them here
    
                // match dates of format m-d-yyyy and convert them to cross-browser-friendly m/d/yyyy
                var mdyyyyDashRegex = /(\d{1,2})-(\d{1,2})-(\d{4})/g;
                arguments[0] = arguments[0].replace(mdyyyyDashRegex, function (match, p1, p2, p3) {
                    return p1 + "/" + p2 + "/" + p3;
                });
            }
    
            // call the original Date constructor with whatever arguments are passed in here
            var date = instantiate(Date, arguments);
    
            return date;
        }
    }(Date);
    

    references:

    • (this post)
    • http://gpf-js.blogspot.com/2016/02/date-override.html
    • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
    • Copying attributes in Javascript

提交回复
热议问题