2010年2月17日水曜日

google closure調査中のメモ(コンパイラの制限事項編)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
まとまった情報が欲しい方はごめんなさい。
ほんとに走り書きです。

オプティマイザの制限

全般的な制限:
1)Ecmascript 262 revision 3.しか理解しません。クロスブラウザなものを作ろうとしているのだから、当然の帰結。
2)コメントが消えてなくなります。JSの最適化とは転送量の削減なので、そういうことです。

SIMPLE_OPTIMIZATIONSに関して
- withを取り扱えない。
- evalもだめ。
- a[""]のたぐいもだめ。

ADVANCED_OPTIMIZATIONSにかんして
関数が消えたり、定数値を計算してしまったり。

スコープ外で定義されている変数を使うこと(コンパイラがスコープの外を見ることができないのでだめ)。
明示的なエキスポートしないで内部の名前を外部で使うこと(コンパイラがリネームしてしまうから)
a.hogeとa["hoge"]を混在させる(後者はリネームの対象にならないため)

外で使う関数なら必ずexportする。でないとコンパイラが消してしまう。このへんはCでgccでも-O2とかにするとなるんじゃなかったっけ?

名前の展開(object property flattening)
{}をネストすると遅くなるので、それへの対策として名前を展開する。
var foo = {};
   foo.bar = function (a) { alert(a) };
   foo.bar("hello");
を次のように変換する。
var foo$bar = function (a) { alert(a) };
   foo$bar("hello");
よってこのコードはthisへの参照が破壊される危険がある。のでthisを使わなければならない、つまりメソッド内(正確にはprototype property)とnew関数のなかでやる必要がある。

To prevent property flattening from breaking your references to this, only use this within constructors and prototype methods. The meaning of this is unambiguous when you call a constructor with the new keyword, or within a function that is a property of a prototype.


function Foo() {
  this.bar = function(a){alert(a)};
  return this;
}

参照破壊系のバグが増えるので、*コンパイル後*のコードを使ってunittestを走らせるとよいかもしれません。

0 件のコメント: