innerHTML = ""
DOMElement を呼び出すと、すべての子とそれらに関連付けられているすべてのイベントが破棄されますか? または、メモリの消費を防ぐためdelete
に呼び出す前に、それらすべてを手動で行う必要がありますか? innerHTML
ありがとう。
4 に答える
delete
JavaScript のメモリ再利用やガベージ コレクションとはまったく関係ありません (C++ で使用されるキーワードと似ていますが)。
を設定するinnerHTML
と、ブラウザーは、呼び出した要素のすべての子孫要素への参照を解放します。通常、これは、これらの要素およびそれらに関連付けられたすべてのイベント ハンドラーがクリーンアップの対象となることを意味します。
IE の古いコピーには問題があり、要素にハンドラーが割り当てられていて、そのハンドラーにも要素への参照 (通常はクロージャーであるため) がある場合、その循環参照によって要素とハンドラーの両方がメモリ内に保持されます。他にそれらへの参照がない場合。たとえば、次のようになります。
function foo() {
var element = document.getElementById("foo");
element.onclick = function() {
// ...do something
};
}
匿名イベント ハンドラは への呼び出しのコンテキストに対するクロージャであるため、 へfoo
の (暗黙の) 参照がありelement
ます。そしてもちろん、element
ハンドラーへの参照があります。これで円が設定されます。古いバージョンの IE は、そのように DOM/JavaScript の境界を越えると、その円を処理できません。
そのため、jQuery などのライブラリは、ハンドラーを解放する前に要素から積極的に削除します (円が壊れるように)。
これは、循環参照が DOM/JavaScript の境界をまたいでいる場合でも、ほとんどの最新のブラウザー (最新バージョンの IE を含む) では問題になりません。
はいinnerHTML
は、すべての子孫を破壊し、添付されたイベントはそれらと一緒に行きます。
innerHTML
vs DOM replaceChild を使用してノードを追加および置換した場合のパフォーマンスを調べた興味深い記事があります。
編集: TJ Crowder が指摘しているように、以前のバージョンの IE には問題があります。IE6 をサポートする必要がない限り、心配する必要はありません (Frit の回答から)。
innerHTML=""
はい、DOMからそれらを削除します。それらがどこからも参照されておらず、ブラウザに特定のメモリ リークがない場合は、ガベージ コレクションに使用できる可能性があります。
delete
キーワードは確かにあなたを助けません。
innerHTML = ""
単に要素を尊重する方法です。これらの要素に存在する一部のデータへの参照がまだある場合、ガベージ コレクターはそれをクリーンアップできない可能性があります。
一般に、複雑なことを何もしていない場合、これによりすべての要素とイベントがクリーンアップされます。古いブラウザーはバグがあることが知られています (IE6 までだと思います) が、最新のすべてのブラウザーでは問題ないはずです。