2011-07-04 22 views
1

高度な最適化機能を備えたGoogle Closure Javascriptコンパイラの問題が発生しています。Googleクローズコンパイラの高度な最適化では一部の変数が最適化されていません

var myClass = function() { 
    this["myFunc"] = this.myFunc; 
    this["myFunc2"] = this.myFunc2; 
}; 
window["myClass"] = myClass; 

myClass.prototype = { 
    myFunc: function() { alert("myFunc"); }, 
    myFunc2: function() { alert("myFunc2"); } 
}; 

問題は時々、何らかの理由で、myFuncmyFunc2が短縮されませんということです、と私は最終的にこのようなコードを参照してください。ドキュメントは、エクスポートJavascriptを維持するために、わかるように私はこのような何かを出力:

x.myFunc=x.myFunc;x.myFunc2=x.myFunc2; 

これは明らかに理想的ではありません。

これを防ぐにはどうすればよいですか?


さらに、いくつかのキーワードがあることが示されています。コンパイルされない「取得」します。

var myClass = function() { 
    this["get"] = this.get; 
    this["myFunc2"] = this.myFunc2; 
}; 
window["myClass"] = myClass; 

myClass.prototype = { 
    get: function() { alert("myFunc"); }, 
    myFunc2: function() { alert("myFunc2"); } 
}; 

私はまだかかわらず、それを引き起こしているのか分からない

function a() { 
    this.get = this.get; 
    this.myFunc2 = this.a 
} 
window.myClass = a; 
a.prototype = {get:function() { 
    alert("myFunc") 
}, a:function() { 
    alert("myFunc2") 
}}; 

にコンパイルします。

答えて

4

私はあなたの問題を複製できません。私はhttp://closure-compiler.appspot.com/homeに移動して、コンパイルすると、次の期待通りの特性が、名前が変更され

function a(){this.myFunc=this.a;this.myFunc2=this.b}window.myClass=a;a.prototype={a:function(){alert("myFunc")},b:function(){alert("myFunc2")}}; 

// ==ClosureCompiler== 
// @compilation_level ADVANCED_OPTIMIZATIONS 
// @output_file_name default.js 
// ==/ClosureCompiler== 

var myClass = function() { 
    this["myFunc"] = this.myFunc; 
    this["myFunc2"] = this.myFunc2; 
}; 
window["myClass"] = myClass; 

myClass.prototype = { 
    myFunc: function() { alert("myFunc"); }, 
    myFunc2: function() { alert("myFunc2"); } 
}; 

は、それから私は、次の結果を得ることができます。

2番目の例では、それはexternsとして知られているClosure Compilerの概念と関係しています。 externは、Webプログラミングの場合、JavaScriptが実行される環境で事前定義されるシンボルです(windowまたはdocumentなど)。このような名前は環境内で修正されるため、コンパイラはこれらの名前を変更することはできません。

CommandLineRunner.javaDEFAULT_EXTERNS_NAMESのリストを見ると、externsフォルダのファイルの一覧が表示されます。これらのファイルの内容は、コンパイラーが知っているエクスターナルを定義します(独自のエクスターナルを追加することもできます)。 webgl.jsw3c_indexeddb.jsの両方とも、get(とそれぞれIDBObjectStore)という名前のプロパティを持つ型を定義します。コンパイラはデフォルトでthisの型がmyClassであることを知らないため、thisWebGLContextAttributesまたはIDBObjectStoreのインスタンスを参照する可能性があります。getの名前を変更することは安全ではありません。

(例えば@constructorなど)タイプ注釈の組み合わせなどambiguatePropertiesdisambiguatePropertiesなどのコンパイラオプションを使用して、コンパイラはthisが常にmyClassの新しいインスタンスを参照し、一貫してgetへの参照のすべての名前を変更することを決定することができます。これらのコンパイラの最適化の詳細については、第14章クロージャ:最終ガイドを参照してください。

+0

更新を参照してください。 –

+0

あなたのアップデートに対応するために私の答えを広げました。 – bolinfest

+0

特にどのアノテーションを使用しますか? –

0

なぜなら、ADVANCED_OPTIMIZATIONSを使用すると、GCCはmyObject ["a"]をmyObject.aとは異なる方法で扱うからです。次のことを試してみてください。

var myObject = {}; 
myObject.attr1 = 3; 
myObject["attr2"] = 4; 
window["myObject"] = myObject; 

それはADVANCED_OPTIMIZATIONSで、これにコンパイルします:

window.myObject={a:3,attr2:4}; 

私はあなたが今何をする必要があるかがわかりますね。あなたが明示的にコンストラクタの外でプロトタイプのメソッドをエクスポートする必要があるようexample hereから

+0

いいえ、私は 'this [" xyz "] = this.xyz'をやっているのです。これは 'window [" myObject "] = myObject'と似ています。 –

1

、それが見えます:

var myClass = function() {}; 
myClass.prototype = { 
    myFunc: function() { alert("myFunc"); }, 
    myFunc2: function() { alert("myFunc2"); } 
}; 

window["myClass"] = myClass; 
myClass.prototype["myFunc"] = myClass.prototype.myFunc; 
myClass.prototype["myFunc2"] = myClass.prototype.myFunc2; 

それは(すべての繰り返し私には奇妙な最適化のように思えるが、これは、宣伝として動作しているようです「プロトタイプ」の参照は多くのバイトを追加します):

function a(){}a.prototype={a:function(){alert("myFunc")}, 
b:function(){alert("myFunc2")}}; 
window.myClass=a; 
a.prototype.myFunc=a.prototype.a; 
a.prototype.myFunc2=a.prototype.b;