How to extend the Javascript Date object?

前端 未结 12 2078
失恋的感觉
失恋的感觉 2020-12-08 14:50

I\'m trying to subclass/extend the native Date object, without modifying the native object itself.

I\'ve tried this:

    var util = require(\'util\')         


        
相关标签:
12条回答
  • 2020-12-08 15:33

    You can also use github.com/loganfsmyth/babel-plugin-transform-builtin-extend

    Example:

    import 'babel-polyfill'
    
    export default class MyDate extends Date {
        constructor () {
            super(...arguments)
        }
    }
    
    0 讨论(0)
  • 2020-12-08 15:35

    Based on the answers by @sstur and its improvement by @bucabay:

    Note that __proto__ is being used in those answers, which is deprecated and its use is strongly discouraged, at least according to the MDN docs.

    Fortunately, it is possible to do what is desired without using __proto__ by setting each individual function from Date.prototype in our class, which is simplified by making use of Object.getOwnPropertyNames().

    function XDate() {
        var x = new (Function.prototype.bind.apply(Date, [Date].concat(Array.prototype.slice.call(arguments))));
    
        Object.getOwnPropertyNames(Date.prototype).forEach(function(func) {
            this[func] = function() {
                return x[func].apply(x, Array.prototype.slice.call(arguments));
            };
        }.bind(this));
    
        this.foo = function() {
            return 'bar';
        };
    }
    

    A minor disadvantage of this method is that XDate isn't actually a subclass of Date. The check xdateobj instanceof Date is false. But this shouldn't be a worry as you can anyway use the methods of the Date class.

    0 讨论(0)
  • 2020-12-08 15:36

    I know this is a bit late, but for others who may encounter this issue, I manged to effectively subclass Date for a polyfill I needed for PhantomJS. The technique seems to work in other browser as well. There were a few additional issues to work out but essentially I followed the same approach as Rudu.

    The full commented code is at https://github.com/kbaltrinic/PhantomJS-DatePolyfill.

    0 讨论(0)
  • 2020-12-08 15:37

    In ES6, it will be possible to subclass built-in constructors (Array, Date, and Error) - reference

    Problem is there is no way to do this with current ES5 engines, as Babel indicates and will require a browser with native ES6 support.

    The current ES6 browser support for subclassing is pretty weak / non-existant as of today (2015-04-15).

    0 讨论(0)
  • 2020-12-08 15:40
    var SubDate = function() { 
        var dateInst = new Date(...arguments); // spread arguments object
        /* Object.getPrototypeOf(dateInst) === Date.prototype */
        Object.setPrototypeOf(dateInst, SubDate.prototype);   // redirectionA
        return dateInst; // now instanceof SubDate
    };
    
    Object.setPrototypeOf(SubDate.prototype, Date.prototype); // redirectionB
    
    // do something useful
    Object.defineProperty(SubDate.prototype, 'year', {
        get: function() {return this.getFullYear();},
        set: function(y) {this.setFullYear(y);}
    });
    
    var subDate = new SubDate(); 
    subDate.year;                                 // now
    subDate.year = 2050; subDate.getFullYear();   // 2050
    

    The problem with the Date constructor function is already explained in the other answers. You can read about the Date.call(this, ...arguments) problem on Date | MDN (first Note).

    This solution is a compact workaround which works as intended in all supporting browsers.

    0 讨论(0)
  • 2020-12-08 15:44

    I believe Date is actually a static function, not a true object, and as such cannot be inherited from using prototypes, so you'll need to create a façade class to wrap any Date functionality you need.

    I'd try constructing your new date object as:

    function MyDate(value) {
      this.value=new Date(value);
    
      // add operations that operate on this.value
      this.prototype.addDays=function(num){
         ...
      };
      this.prototype.toString=function() {
        return value.toString();
      };
    }
    // add static methods from Date
    MyDate.now=Date.now;
    MyDate.getTime=Date.getTime;
    ...
    

    (I'm not near a system I can test this on, but I hope you get the idea.)

    0 讨论(0)
提交回复
热议问题