2012-04-01 12 views
3

ich versuche, dieses Stück Code zum Laufen zu bringen:Closure Compiler gilt nicht @const auf diese

/** @constructor */ 
function Foo() 
{ 
    /** @const */ 
    this.bar = 5; 

    // edit: does now work 
    // this.bar = 3; 
} 

var f = new Foo(); 

// should be inlined (like other constants) 
alert(f.bar); 

Ich habe bereits versucht, mehr Anmerkungen hinzugefügt (Typen, Konstruktor), @enum statt @const (für this.bar), me = this, die alle keine Wirkung hatten.

Die help page war nicht wirklich hilfreich dabei.

Gibt es einen Weg, um das zu erreichen? Wenn nicht, warum?

Antwort

2

Der Compiler hat keine allgemeine "Inline-Eigenschaften" -Logik. Sie können dies im erweiterten Modus Inline erhalten, indem eine Prototyp-Funktion:

/** @constructor */ 
function Foo() {} 
Foo.prototype.bar = function() { return 5 }; 

var f = new Foo(); 
alert(f.bar()); 

kompilieren zu:

alert(5); 

Der Compiler wird dies tun, wenn es nur eine einzige Definition einer Methode „bar ist "und" bar "wird immer nur in einem Aufrufausdruck verwendet. Die dafür verwendete Logik ist im allgemeinen Fall nicht korrekt (wenn sich der Aufruf auf einem Objekt befindet, das keinen "Balken" definiert, würde der Aufruf ausgelöst). Es gilt jedoch als "sicher genug".

+0

Wenn vorangestellt mit der" @ const "Annotation wird eine Variable inline (bekannt als [konstante Propagation] (http: //en.wikipedia.org/wiki/Constant_propagation)) durch den Closure Compiler, der für normale 'var'-Zustände gut funktioniert.Das ist das Verhalten, das ich mit Eigenschaften zu reproduzieren versuche.Es hat etwas mit dem Prozess zu tun, den du beschrieben hast – copy

+0

Wie gesagt, der Compiler hat keine Unterstützung dafür. Es prüft @const-Annotationen auf Klasseneigenschaften, wenn es möglich ist, aber es ist konservativer, diese Informationen bei der Optimierung tatsächlich zu verwenden. – John

+0

Ich spielte mit dem Compiler ein bisschen mehr herum, dachte aber, dass du recht hast; Es scheint keinen Weg zu geben, dies zu tun. Jedenfalls benutze ich jetzt cpp. – copy

2

Hinzufügen /** @constructor */ Werke:

/** @constructor */ 
function Foo() 
{ 
    /** @const */ 
    this.bar = 5; 

    // cc does not complain 
    //this.bar = 3; 
} 

var f = new Foo(); 

// should be inlined 
alert(f.bar); 

kompiliert:

alert((new function() { this.a = 5 }).a); 

wenn ich Kommentar- die this.bar = 3; ich diese erwartete Warnung erhalten:

JSC_CONSTANT_PROPERTY_REASSIGNED_VALUE: constant property bar assigned a value more than once at line 9 character 0 
this.bar = 3; 
^ 
+0

Es ist immer noch nicht inline 'f.bar' in der gleichen Weise wie andere Konstanten. Dies sollte "alert (5)" ausgeben. – copy

+0

http://code.google.com/p/closure-compiler/issues/detail?id=287 :( – stewe

+0

Nun, das klingt wie schlechte Nachrichten, +1 für Ihre Hilfe sowieso. Immer noch auf der Suche nach einem Hack, um dies zu tun – copy

0

In der Dokumentation wird gesagt, dass:

Der Compiler gibt eine Warnung aus, wenn einer Variablen, die mit @const gekennzeichnet ist, ein Wert mehr als einmal zugewiesen wird. If the variable is an object, note that the compiler does not prohibit changes to the properties of the object.

S.S .: Haben Sie den folgenden Code in Ihr Skript oder Ihre HTML-Seite eingefügt?

<script src="closure-library/closure/goog/base.js"></script> 
+0

Der von Ihnen zitierte Text besagt, dass Sie immer noch die Eigenschaften eines konstanten Objekts ändern können.Es ist jedoch möglich, eine Eigenschaft eines Objekts als konstant zu markieren (siehe auch Stewes Antwort). Ich versuche, es mit dem '' zu arbeiten new "-Operator. Ich verwende auch nicht Closure-Bibliothek in meinem Skript. Closure Compiler funktioniert perfekt ohne. – copy

Verwandte Themen