为什么谷歌闭包编译器在扩展Date()的ES6对象上失败

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

本文关键字:ES6 对象 失败 Date 闭包 谷歌 编译器 扩展 为什么      更新时间:2023-09-26

请注意:这个问题涉及到谷歌闭包编译器的使用。它不是直接关于ES6的,因为那部分正在工作。

我在ES6中写了一个类,它扩展了本机Date对象。这是一个很大的类,但这是一个简化的版本:

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

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

上面的代码在Chrome和Firefox中运行良好。然而,当我通过闭包编译器传递它时,它会抛出错误:

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

Update:调用本机Date方法在编译版本中也会失败,但未编译时可以正常工作,并显示一条消息说这不是Date对象。

我不明白的是为什么以原始形式工作的代码在编译后会中断。

是我做错了什么,还是这是一个编译器错误?

我使用的是最新版本的compiler.jar。作为参考,这是闭包编译器产生的结果:

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

Date在ES5中不可子类化。所以你想要的在ES5环境中是不可能实现的。

编译后的代码也不能在ES6环境中工作。来自规范

Date构造函数被设计为可子类化的。它可以用作类定义的extends子句的值。想要继承指定的Date行为的子类构造函数必须包含对Date构造函数的超调用,以创建和初始化具有[[DateValue]]内部槽位的子类实例。

如果不调用super,它将无法工作。Date.call(this);不起作用。基本上,如果你将代码编译到ES5,子类化内置类型是不允许的。

所以这不是Google Closure的问题