0

次のコードがバージョン8より前のIEでメモリリークを引き起こすと主張されているオンラインJavaScriptチュートリアルを読んでいます。

function setHandler() {
  var elem = document.getElementById('id')
  elem.onclick = function() { /* ... */ }
}

作成者は、メモリリークを防ぐための修正も提供しました。

function setHandler() {
  var elem = document.getElementById('id')
  elem.onclick = function() { /* ... */ }
  elem=null;
}

元のコードがメモリリークを引き起こすのはなぜですか?また、修正によってそれを防ぐにはどうすればよいですか?

4

1 に答える 1

3

この記事は良い説明をしています。問題はIEと循環参照です。

つまり、次のことを行います。

function setHandler() { 
  var elem = document.getElementById('id') // (1)
  elem.onclick = function() { /* ... */ } //(2)
}

関数の最初の行は2番目の行を参照し、2番目の行は最初の行を参照しているため、IEはelem変数を作成するために割り当てたメモリを解放しません。

次の行でelemの値を「破棄」することにより、2番目の参照を明示的に削除することにより、参照を解除しています。

elem = null

IEがメモリを解放できるようにする

2番目の参照は、クロージャに問題があるために発生します。onclickにバインドされた内部関数はアクセスできるためelem(関数スコープに存在します)、そこで「ロック」されます。

つまり、elemへの参照は2つあります。1つはvarステートメントで作成され、もう1つはonclick関数で作成され、その参照はクロージャーが解放されるまで解放されません。

あなたはここここ、そしてこのスタックオーバーフローの答えでより多くの情報を見つけることができます

于 2012-08-07T02:37:17.207 に答える