How to extend the Javascript Date object?

前端 未结 12 2114
失恋的感觉
失恋的感觉 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:50

    This can be done in ES5. It requires modifying the prototype chain directly. This is done using __proto__ or Object.setPrototypeOf(). I'm using __proto__ in the sample code since that's most widely supported (although the standard is Object.setPrototypeOf).

    function XDate(a, b, c, d, e, f, g) {
      var x;
      switch (arguments.length) {
        case 0:
          x = new Date();
          break;
        case 1:
          x = new Date(a);
          break;
        case 2:
          x = new Date(a, b);
          break;
        case 3:
          x = new Date(a, b, c);
          break;
        case 4:
          x = new Date(a, b, c, d);
          break;
        case 5:
          x = new Date(a, b, c, d, e);
          break;
        case 6:
          x = new Date(a, b, c, d, e, f);
          break;
        default:
          x = new Date(a, b, c, d, e, f, g);
      }
      x.__proto__ = XDate.prototype;
      return x;
    }
    
    XDate.prototype.__proto__ = Date.prototype;
    
    XDate.prototype.foo = function() {
      return 'bar';
    };
    

    The trick is that we actually instantiate a Date object (with the correct number of arguments) which gives us an object with it's internal [[Class]] set correctly. Then we modify it's prototype chain to make it an instance of XDate.

    So, we can verify all this by doing:

    var date = new XDate(2015, 5, 18)
    console.log(date instanceof Date) //true
    console.log(date instanceof XDate) //true
    console.log(Object.prototype.toString.call(date)) //[object Date]
    console.log(date.foo()) //bar
    console.log('' + date) //Thu Jun 18 2015 00:00:00 GMT-0700 (PDT)
    

    This is the only way I know of to subclass date because the Date() constructor does some magic to set the internal [[Class]] and most date methods require that to be set. This will work in Node, IE 9+ and almost all other JS engines.

    Similar approach can be used for subclassing Array.

提交回复
热议问题