1

高度な最適化を備えた Google Closure Javascript コンパイラで問題が発生しています。ドキュメントが示唆するように、エクスポートされた Javascript を保持するには、次のようにします。

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ないことがあり、最終出力に次のようなコードが表示されることです。

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

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

どうすればこれを防ぐことができますか?


さらに実験を重ねた結果、'get' などの特定のキーワードがコンパイルされないことが示されました。

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

3 に答える 3

4

私はあなたの問題を再現することはできません。http://closure-compiler.appspot.com/homeにアクセスして、以下をコンパイルすると、次のようになります。

// ==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"); }
};

次に、次の結果が得られます。

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

予想どおり、プロパティの名前が変更されました。

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

CommandLineRunner.javaDEFAULT_EXTERNS_NAMESのリストを見ると、 externsフォルダーのファイルのリストが表示されます。これらのファイルの内容は、コンパイラが認識しているexternを定義します(独自のexternを追加することもできます)。とは、 (および、)という名前のプロパティを持つ型を定義します。デフォルトでは、コンパイラはinのタイプを認識していません。それがわかっている限り、またはのインスタンスを参照できます。その場合、名前を変更するのは安全ではありません。webgl.jsw3c_indexeddb.jsgetWebGLContextAttributesIDBObjectStorethismyClassthisWebGLContextAttributesIDBObjectStoreget

型注釈(など@constructor)とコンパイラオプション(ambiguatePropertiesおよびなど)を組み合わせて使用​​することにより、コンパイラは、が常にの新しいインスタンスを参照するdisambiguatePropertiesことを決定し、そのすべての参照の名前を一貫して変更できます。これらのコンパイラの最適化の詳細については、Closure:TheDefinitiveGuideの第14章を参照してください。thismyClassget

于 2011-07-06T04:42:22.563 に答える
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;
于 2011-07-04T20:47:32.717 に答える