3

テスト要素を作成する関数があります。関数を返す前に、メモリ リークを防ぐためにテスト要素への参照を無効にしています。しかし、クロージャーコンパイラーは、その行 b/c を削除しています (両方のモードで)。行が削除されないようにするために追加できるコメントはありますか?

function isExample (testElem) {
 var bool; 
 testElem = testElem || document.createElement('div');

 // Do stuff in here to determine `bool`
 // ...

 // Then nullify the reference
 testElem = null; // The compiler removes this line. How do I make it keep it?

 return bool;
}
4

2 に答える 2

5

必要ありません。ガベージ コレクターも同じことを行うため、Google Closure Compiler はそれを削除するだけです。

これでメモリをリークするガベージコレクタは知りませんもしあれば、JSにはかなり大きな問題があります。

JS には関数スコープがあることに注意してください。つまり、関数で定義された変数は、実行が関数の外に出るとガベージ コレクションされます。

これは、ガベージ コレクターの基本的な機能の 1 つです。js エンジンがこれでメモリ リークを起こすと、深刻な問題になります。

testElement = []古い IE リークの場合、コンパイラを無効化した後に追加することで、コンパイラを回避しようとする場合があります。

于 2012-06-14T07:56:47.837 に答える
2

この場合、コンパイラは正しいです。ただし、コードを維持することに完全に固執している場合は、引用符で囲まれた構文を使用して、値をエクスポートするか、シンクオブジェクトを使用する必要があります。

function sinkValue(x) {
  sinkValue[' '](x);
  return x;
}
sinkValue[' '] = function(){};

function isExample (testElem) {
  var bool;
  var obj = { 'elem': testElem || document.createElement('div') };

  // Do stuff in here to determine `bool`
  // ...

  obj['elem'] = null;
  sinkValue(obj);

  return bool;
}

引用符で囲まれた構文は、名前の変更とデッドコードの除去の両方を防ぐため、そのオブジェクトプロパティでのこれらの最適化を無効にすることになります。この場合、関数を超えてオブジェクトの寿命を延ばしていますが(これは意図の逆のようです)。

必要なものを正確に指定するための注釈はありません。これに関連するディスカッションは、次の場所で確認できます。

コンパイラは、役に立たないコードを削除するという点で、意図したとおりに実行しています。

于 2012-06-14T13:14:02.647 に答える