10

なぜそれが優れているのか、そしてそれがどのように実装されているのかを読みました。しかし、私が本当に理解していないのは、循環参照をどのように壊すのかということです。

どのように参照円を壊しますか?

$(div1).data('item', div2);
$(div2).data('item', div1);

例のように、上記のdivは互いに指し示していますが、どのように防止されますか?私には予感がありますが、自分の予感が正しいかどうかを確認したいだけです。

4

1 に答える 1

15

一部のブラウザでは、DOMオブジェクトのプロパティとしてDOMオブジェクトのDOMオブジェクトへの参照を配置すると、循環参照の問題が発生します。次に、2つのDOMオブジェクトが互いに向き合っています。カスタムプロパティを持つDOMオブジェクトを削除しても、そのカスタムプロパティはクリアされません。それほど賢くないガベージコレクターは、このDOM参照がカウントされないことを認識しないため、スタックし、これがリークにつながる可能性のあるいくつかの方法があります。

.data().data()データがDOMオブジェクト上にないため、この問題を解決します。これは、一意の文字列IDを介してDOMオブジェクトに関連付けることができる単なるJavaScriptデータ構造です。

これの1つの紛らわしい部分は、を読んで.data("key")keyjavascriptデータ構造にが見つから.data()ない場合、jQueryはと呼ばれるDOMオブジェクトの属性を検索することです"data-key"。ただし、を使用して書き込む場合は常に.data("key", "myData")、DOMオブジェクトに書き込むことはなく、javascriptデータ構造にのみ書き込みます。

したがって、.data()DOMオブジェクトにデータを書き込むことは決してないため、一部のブラウザーで問題が発生するこれらのタイプの循環参照はあり得ません。

.data()データ構造について知っておくと便利なことが他にもいくつかあります。jQueryを使用.remove()してDOMから要素を削除する場合、またはを呼び出す場合、jQueryは削除されたアイテム$(elem).html("new html")のデータをクリアします。.data()これは、jQueryとプレーンなjavascriptを混在させない方がよい場合の1つです。を使用している場合は.data()、jQuery関数を使用してDOMからアイテムを常に削除する必要があるため、.data()適切にクリーンアップされます。そうしないと、この方法でメモリリークが発生する可能性があります(.data()データがリークする可能性があり、で参照されている削除されたDOMオブジェクトが.data()リークする可能性があります。ただし、DOMからアイテムを削除するためにjQueryメソッドのみを使用する場合(innerHTMLの置換を含む)、そうすれば、jQueryは適切にクリーンアップし、リークは発生しません。

したがって、たとえば、これによりメモリリークが発生します。

// suppose elem is a DOM element reference

// store some data in jQuery's data storage on behalf of a DOM element
$(elem).data("someKey", "someValue");

// remove DOM element with plain Javascript
elem.parentNode.removeChild(elem);

プレーンなJavascriptでDOM要素を削除したため、jQueryには以前に保存したデータをクリーンアップする機会がありませんでした。DOM要素自体はガベージコレクションされ.data()ますが、以前に保存した値はjQueryのストレージで孤立し、クリアされることはない可能性が高いため、本質的に「リーク」になります。一方、これを行う場合:

$(elem).data("someKey", "someValue");
$(elem).remove();

次に、jQueryは、DOM要素を削除していることを確認し、で保存したデータもクリアします.data()

$(elem).data("key", "whatever")それがどのように機能するかを確認する非常に簡単な方法は、最小化されていないバージョンのjQueryを使用して数行のスクリプトを作成し、デバッガーでの呼び出しをステップ実行して、どのように機能するかを確認することです。

于 2012-04-04T03:46:20.467 に答える