Why is Google Closure Compiler failing on my ES6 object which extends Date()?

蓝咒 提交于 2019-12-07 10:45:07

问题


Please note: this question relates to the use of Google's Closure Compiler. It's not directly about ES6, since that part is working.

I've written a class in ES6 which extends the native Date object. It's a large class, but this is a simplified version:

   class Dative extends Date {

       constructor (dateData) {
           super();
           super.setTime(Date.parse(dateData));
       }


       addMilliseconds (ms) {
           super.setTime(super.getTime() + ms);
       }

   }

The code above works fine in Chrome and Firefox. However, when I pass it through Closure Compiler, it throws errors:

Uncaught TypeError: Method Date.prototype.setTime called on
incompatible receiver [object Object]

Update: calling native Date methods also fails in the compiled version but works fine uncompiled, with a message saying this is not a Date object.

What I don't understand is why code that works in its original form breaks when it's been compiled.

Am I doing something wrong, or is this a compiler bug?

I'm using the latest version of compiler.jar. For reference, this is what closure compiler produces:

var $jscomp = {
    scope: {},
    inherits: function(a, b) {
        function d() {}
        d.prototype = b.prototype;
        a.prototype = new d;
        a.prototype.constructor = a;
        for (var c in b)
            if (Object.defineProperties) {
                var e = Object.getOwnPropertyDescriptor(b, c);
                e && Object.defineProperty(a, c, e)
            } else
                a[c] = b[c]
    }
}
  , Dative = function(a) {
    Date.call(this);
    Date.prototype.setTime.call(this, Date.parse(a))
};

$jscomp.inherits(Dative, Date);
Dative.UTC = Date.UTC;
Dative.parse = Date.parse;
Dative.now = Date.now;
Dative.prototype.addMilliseconds = function(a) {
    Date.prototype.setTime.call(this, Date.prototype.getTime.call(this) + a)
};
//# sourceMappingURL=./DativeShort.map

回答1:


Date is not subclassable in ES5. So what you want is not possible in ES5 environments in the first place.

The transpiled code cannot work in ES6 environments either. From the specification

The Date constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Date behaviour must include a super call to the Date constructor to create and initialize the subclass instance with a [[DateValue]] internal slot.

Without calling super it won't work. Date.call(this); doesn't do the trick. Basically, if you transpile code to ES5, subclassing built-in types is a no-go.

So no, it's not a problem of Google Closure.



来源:https://stackoverflow.com/questions/38954597/why-is-google-closure-compiler-failing-on-my-es6-object-which-extends-date

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