2016-08-15 2 views
4

Hinweis: Diese Frage bezieht sich auf die Verwendung von Google Closure Compiler. Es geht nicht direkt um ES6, da dieser Teil funktioniert.Warum scheitert Google Closure Compiler an meinem ES6-Objekt, wodurch Date() verlängert wird?

Ich habe eine Klasse in ES6 geschrieben, die das native Date-Objekt erweitert. Es ist eine große Klasse, aber dies ist eine vereinfachte Version:

class Dative extends Date { 

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


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

    } 

Der obige Code funktioniert gut in Chrome und Firefox. Allerdings, wenn ich es durch Closure Compiler passieren, wirft es Fehler:

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

Update: Aufruf nativer Datum Methoden auch in der kompilierten Version nicht funktioniert aber einwandfrei kompilierte, mit einer Meldung, das ist kein Date-Objekt.

Was ich nicht verstehe ist, warum Code, der in seiner ursprünglichen Form funktioniert, bricht, wenn es kompiliert wurde.

Mache ich etwas falsch, oder ist das ein Compiler Bug?

Ich verwende die neueste Version von compiler.jar. Als Referenz ist das, was Schließung Compiler erzeugt:

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 
+0

Als Bug ausgelöst: https://github.com/google/closure-compiler/issues/1953 – beingmrkenny

Antwort

1

Date in ES5 nicht ableitbaren ist. Was Sie wollen, ist in ES5-Umgebungen überhaupt nicht möglich.

Der transpilierte Code kann auch nicht in ES6-Umgebungen funktionieren. Von specification

Der Date-Konstruktor ist so konzipiert, dass er unterklassierbar ist. Es kann als Wert einer extends-Klausel einer Klassendefinition verwendet werden. Unterklassenkonstruktoren, die beabsichtigen, das angegebene Date-Verhalten zu erben, müssen einen Superaufruf zum Date-Konstruktor enthalten, um die Unterklasseninstanz mit einem internen [[DateValue]] - Slot zu erstellen und zu initialisieren.

Ohne Aufruf super wird es nicht funktionieren. Date.call(this); macht den Trick nicht. Wenn Sie Code nach ES5 transpilieren, ist das Unterklassifizieren von integrierten Typen grundsätzlich ein No-Go.

Also nein, es ist kein Problem von Google Closure.

+0

Ich glaube, das ist richtig. Ich habe bestätigt, dass Babels Transpiration auch nicht funktioniert. –

+0

Danke, nützliche Informationen. Ich hatte gehofft, Closure würde wissen, wie man ES6-Verhalten in ES5 repliziert :( – beingmrkenny

Verwandte Themen