1

入力 JavaScript の最小限の例を次に示します (別の言語によって生成されますが、それはここでもそこでもありません)。

goog.provide('foo.bar');
foo.bar.baz = 42;
goog.exportSymbol('foo.bar.baz', foo.bar.baz);
foo.bar.quux = (function quux(){return foo.bar.baz;
});
goog.exportSymbol('foo.bar.quux', foo.bar.quux);

私の期待はfoo.bar.baz、定数として注釈が付けられていないため、定数として扱われないことです。それでも、高度な最適化 (ローカルおよびコンパイラ サービス経由の両方) は、いずれにせよインライン化します。

var d = this;
function f(g, e) {
  var b = g.split("."), a = d;
  b[0] in a || !a.execScript || a.execScript("var " + b[0]);
  for (var c;b.length && (c = b.shift());) {
    b.length || void 0 === e ? a = a[c] ? a[c] : a[c] = {} : a[c] = e;
  }
}
;f("foo.bar.baz", 42);
f("foo.bar.quux", function() {
  return 42;
});

一定のインライン化は優れていますが、問題の値はエクスポートされているため、インライン化することは安全ではありません。goog.exportPropertyと の代わりにと@exposeの注釈を使用してみましたがgoog.exportSymbol、うまくいきませんでした。

ヘルプ?ありがとう!

4

1 に答える 1

0

更新:@expose現在は非推奨です。回答が新しい方法で更新されました。

ご指摘のとおり@const、インライン化には影響しません。@constonly は、値が変更されないことを意味します (一度だけ割り当て/設定されます)。

@nocollapseプロパティの崩壊を防ぐために特別に作成されました。与えられた:

goog.provide('foo.bar');
/** @nocollapse */
foo.bar.baz = 42;
alert(foo.bar.baz);

この場合の目的は@nocollapse、コンパイラがプロパティを次のように折りたたまないようにすることです。

var a = 42;
alert(a);

ただし、コンパイラはフロー解析からfoo.bar.baz、整数が割り当てられ、42変更されていないことを認識しています。したがって、既知の値を使用するだけです。

インライン化を防ぐ唯一の確実な方法は、プロパティをエクスポートすることです。

goog.provide('foo');
goog.provide('foo.bar');
foo.bar.baz = 42;
goog.exportProperty(foo.bar, 'baz', foo.bar.baz);
alert(foo.bar.baz);

名前の変更は安全であるが、インライン化は安全ではないことをコンパイラに規定する必要があることが (小さいながらも) 知られています。https://code.google.com/p/closure-compiler/issues/detail?id=971を参照してください

クロージャ ライブラリを使用していない場合、エクスポートは次のようになります。

var foo = {};
foo.bar = {};
/** @nocollapse */
foo.bar.baz = 42;
foo.bar['baz'] = foo.bar.baz;
alert(foo.bar.baz);

あなたの目標がfoo.bar.bazインライン化または名前変更されていないことを確認することである場合は、引用符で囲まれたプロパティと@nocollapse.

goog.provide('foo');
goog.provide('foo.bar');
/** @nocollapse */
foo.bar.baz = 42;
goog.exportProperty(foo.bar, 'baz', foo.bar.baz);
alert(foo.bar.baz);

この名前空間を他のユーザーに提供して使用する場合、最適なケースは、 を組み合わせ@nocollapseて崩壊を防ぎ、外部更新を許可することgoog.exportSymbolです。

goog.provide('foo');
goog.provide('foo.bar');
/** @nocollapse */
foo.bar.baz = 42;
goog.exportSymbol('foo', foo);
goog.exportProperty(foo, 'bar', foo.bar);
goog.exportProperty(foo.bar, 'baz', foo.bar.baz); 

alert(foo.bar.baz);
于 2013-11-08T14:32:10.693 に答える