4

これが単なるバグなのか意図した機能なのかはわかりません。

基本的に、私はこの小さな関数を持っています(endここでは青色に着色されていますが、これは問題なく機能します。名前を別の名前に変更すると、まだ問題があります):

function f(a, b) {
    var start = Math.min(a, b);
    var end = Math.max(a, b);

    tb.selectionStart = start;
    tb.selectionEnd = end;
};

それをクロージャーコンパイルすると、次のようになります。

function f(a,b){var c=Math.max(a,b);tb.selectionStart=Math.min(a,b);tb.selectionEnd=c};

しかし、最初に宣言された変数 ( ) に設定されているのに、直接にselectionStart設定されているのはなぜですか? やるほうが短くないですか?Math.minselecitonEndctb.selectionEnd=Math.max(a,b)

どんなアイデアでも大歓迎です。

4

2 に答える 2

4

編集: このリンクに「公式」の回答があります: https://web.archive.org/web/20151226143155/http://code.google.com/p/closure-compiler/issues/detail?id=410

変数への代入の直後にその変数を使用すると、インライン化できると思います。ただし、間に副作用がないことが証明できないステートメントがある場合、コンパイラはそれをインライン化しません。

あなたの場合、変数「start」への割り当ては、「end」への割り当てステートメントによってのみ「start」の使用法から分離されています。ただし、Math.max は内部関数であり、コンパイラはこれに副作用がないことを認識しているため、このステートメントには副作用がありません。

ただし、あなたの場合、変数「end」への割り当ては、プロパティへの「start」の割り当てであるステートメントによってその変数の使用法から分離されています。さて、コンパイラは、単にプロパティに代入するだけで常に副作用がないとは想定していないと思います。これは、一部のプロパティが割り当てられると、実際には異なる動作を引き起こしたり、グローバル状態 (RegExp など) を変更したりするためです。一部のシステムでは、プロパティの割り当てによって、特定のシステム固有の機能 (ハードウェア インターフェイスなど) が実際にトリガーされ、副作用が含まれる場合があります。

そのため、次のようなコードがある場合があります。

foo.bar = 1;
foo.bar = 2;
foo.bar = 3;

「bar」への割り当てには副作用がある可能性があるため、コンパイラは最初の 2 つのステートメントを削除しません。

したがって、あなたの質問では、ステートメントtb.selectionStart = start;に副作用がある可能性があるため、変数「end」をインライン化することはできません(おそらく奇妙な場合にのみ)。

"tb" をローカル変数、またはコンパイラが完全に制御できるもの (単純なオブジェクト:var tb = {};など) にすると、コンパイラがすべての代入を問題なくインライン化することがわかります。

于 2011-04-06T12:56:11.907 に答える
3

このコードを貼り付けると、これが機能します。

function f(a, b) {
    var start = Math.min(a, b);
    tb.selectionStart = start;

    var end = Math.max(a, b);
    tb.selectionEnd = end;
};

function f(a,b){tb.selectionStart=Math.min(a,b);tb.selectionEnd=Math.max(a,b)};

これはクロージャ コンパイラによるミスです。

于 2011-04-06T11:28:57.193 に答える