2

コードをいくつかのファイルに分割し、スクリプトを実行してそれらをマージおよびコンパイルします ( ADVANCED_OPTIMIZATIONS. 機能の大部分は、単一のオブジェクトのプロトタイプに実装されています。

したがって、マージすると、次のようになります。

(function(){

/** @constructor */ function MyConstructor() {};

MyConstructor.prototype = {};

MyConstructor.prototype['foo'] = function() { alert('foo'); };
MyConstructor.prototype['bar'] = function() { alert('bar'); };
MyConstructor.prototype['baz'] = function() { alert('baz'); };

window['MyConstructor'] = MyConstructor;

}());

そのコードをそのようにClosure Compilerに入れると、出力は次のようになります (きれいに印刷されています)。

function a() {
}
a.prototype = {};
a.prototype.foo = function() {
  alert("foo")
};
a.prototype.bar = function() {
  alert("bar")
};
a.prototype.baz = function() {
  alert("baz")
};
window.MyConstructor = a;

問題は、これらすべてを 1 つのオブジェクト リテラルにマージしても問題ないことを Closure Compiler に伝える方法があるかどうか、また間にコードがあったとしても (この例ではありませんが、存在する可能性があります) 、何があっても、すべてを1つの大きなオブジェクトリテラルにコンパイルしましたか?

ここにいくつかの解決策と、それらがうまくいかない理由を示します。

  • 解決策 1: 1 つの大きなオブジェクト リテラルで宣言するだけです。
    私は自分のコードを複数のファイルに分けているため、機能しません。コンパイルの前に、ユーザーがそれらの一部を (不要な場合は) 削除できるようにする予定です。オブジェクト リテラルには、これを悪夢にするカンマ区切り文字があります。
  • 解決策 2 : すべての機能をオブジェクトの外部で宣言し (クロージャー内のプライベート変数として)、それらを最後に簡略化されたオブジェクト リテラルにアタッチします。これには、プロパティ ( など{'foo':foo,'bar':bar,'baz':baz}) への参照のみが含まれます。前述のように、アイデアはモジュラーなものを作成することであり、1つのファイルを削除すると参照が壊れるため、機能し
    ません。

私はアイデアを受け入れます!


編集:一部の人々は、Closure Compiler ではこれができないと考えているかもしれません。それはこれを行うことができ、それ以上のことを行うことができますが、それは態度が悪く、気が向いたときに物事を行うだけです.

これを Closure に入力します。

(function(){

var MyConstructor = window['MyConstructor'] = function() {};

var myProto = {
    'foo': function() { alert('foo'); },
    'bar': function() { alert('bar'); }
};

myProto['baz'] = function() { alert('baz'); };

MyConstructor.prototype = myProto;

}());

結果は次のとおりです。

(window.MyConstructor = function() {
}).prototype = {foo:function() {
  alert("foo")
}, bar:function() {
  alert("bar")
}, baz:function() {
  alert("baz")
}};

見る?しかし、これは非常に脆弱なコードで、わずかに変更すると、コンパイルするとまったく異なる (あまり良くない) ものになる可能性があります。たとえば、中間のどこかに変数を割り当てても、非常に異なる結果が出力される可能性があります。つまり、これは機能しません (この場合を除く)。


編集 2:このjsperfを参照してください。大きなオブジェクト リテラルは、Chrome の方が高速です (そのサイズに比例します)。


編集 3: Closure Compiler バグ レポート

4

1 に答える 1

0

私がやっている回避策があります。当てはまらない可能性があるため、この回答は受け入れられません。それでも、これは私の場合に機能します。

私のフォルダ構造は次のようになりました:

src
├───components
└───core

そして、コンパイルの前にsrc/intro.js、レベルのいくつかのファイルをsrc(特定の順序で)マージし、次にすべてのファイルをcore(任意の順序で)、次にすべてをcomponents(任意の順序で)、次にoutro.js.

これで、フォルダー構造は次のようになります。

src
├───components
│   ├───modules
│   └───plugs-literal
└───core
    ├───internal
    ├───modules
    └───plugs-literal

コンパイルの順序は次のとおりです (矢印の部分に注意してください)。

  • src/intro.js
  • src/core特定の順序でいくつかのファイル。
  • 内のすべてのファイルsrc/core/internal
  • src/core/plugs-literal-intro.js <--
  • <--内のすべてのファイルsrc/core/plugs-literal
  • <--内のすべてのファイルsrc/components/plugs-literal
  • src/core/plugs-literal-outro.js <--
  • 内のすべてのファイルsrc/core/modules
  • 内のすべてのファイルsrc/components/modules
  • src/outro.js

1 つのファイルにはオブジェクト リテラルの先頭が含まれ、別のファイルにはオブジェクト リテラルの終了が含まれ、2 つのフォルダーにはプロパティが含まれます。多かれ少なかれ次のように:

src/core/plugs-literal-intro.js:

var myObjectLiteral = {
    'someSimpleProp': 'foo',
    'someOtherSimpleProp': 'bar',
    'lastOneWithoutTrailingComma': 'baz'

src/core/plugs-literal/EXAMPLE.js:

,'example': function() { alert('example'); } // comma before, not after.

src/core/plugs-literal-outro.js:

};

これにより望ましくない問題が発生した場合は、後でわかります。しかし、別のフォルダーを割り当てて、個別に宣言されたプロトタイプ プロパティを含めることができます。

于 2012-09-30T21:47:18.550 に答える