Jawaban:
JavaScript polos
Jika elemen DOM yang dihapus bebas referensi (tidak ada referensi yang menunjukkannya), maka ya - elemen itu sendiri diambil oleh pengumpul sampah serta penangan / pendengar acara yang terkait dengannya.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
b = null;
// A reference to 'b' no longer exists
// Therefore the element and any event listeners attached to it are removed.
Namun; jika ada referensi yang masih menunjuk ke elemen tersebut, elemen dan pendengar acara tetap disimpan dalam memori.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
// A reference to 'b' still exists
// Therefore the element and any associated event listeners are still retained.
jQuery
Akan adil untuk mengasumsikan bahwa metode yang relevan di jQuery (seperti remove()
) akan berfungsi dengan cara yang persis sama (mengingat remove()
ditulis menggunakan menggunakan removeChild()
misalnya).
Namun, ini tidak benar ; pustaka jQuery sebenarnya memiliki metode internal (yang tidak berdokumen dan secara teori dapat diubah kapan saja) yang disebut cleanData()
(inilah yang terlihat seperti metode ini ) yang secara otomatis membersihkan semua data / peristiwa yang terkait dengan elemen setelah dihapus dari DOM (menjadi ini melalui. remove()
, empty()
, html("")
dll).
Peramban yang lebih lama - khususnya versi IE yang lebih lama - diketahui memiliki masalah kebocoran memori karena pendengar acara tetap memegang referensi ke elemen yang dilampirkan.
Jika Anda menginginkan penjelasan yang lebih mendalam tentang penyebab, pola, dan solusi yang digunakan untuk memperbaiki kebocoran memori versi IE lama, saya sepenuhnya menyarankan Anda membaca artikel MSDN ini tentang Memahami dan Memecahkan Pola Kebocoran Internet Explorer.
Beberapa artikel yang relevan dengan ini:
Menghapus sendiri pendengar secara manual mungkin merupakan kebiasaan yang baik untuk digunakan dalam kasus ini (hanya jika ingatannya begitu vital bagi aplikasi Anda dan Anda benar-benar menargetkan browser semacam itu).
remove
metode. sebagian besar waktu DOM hanya akan terhapus sepenuhnya. (seperti tautan turbo atau sesuatu). Saya bertanya-tanya bagaimana memori terpengaruh jika saya lakukan document.body.innerHTML = ''
...
tentang jQuery:
metode .remove () mengeluarkan elemen dari DOM. Gunakan .remove () saat Anda ingin menghapus elemen itu sendiri, serta semua yang ada di dalamnya. Selain elemen itu sendiri, semua acara terikat dan data jQuery yang terkait dengan elemen dihapus. Untuk menghapus elemen tanpa menghapus data dan acara, gunakan .detach () sebagai gantinya.
Referensi: http://api.jquery.com/remove/
.remove()
kode sumber jQuery v1.8.2 :
remove: function( selector, keepData ) {
var elem,
i = 0;
for ( ; (elem = this[i]) != null; i++ ) {
if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
if ( !keepData && elem.nodeType === 1 ) {
jQuery.cleanData( elem.getElementsByTagName("*") );
jQuery.cleanData( [ elem ] );
}
if ( elem.parentNode ) {
elem.parentNode.removeChild( elem );
}
}
}
return this;
}
rupanya jQuery menggunakan node.removeChild()
Menurut ini: https://developer.mozilla.org/en-US/docs/DOM/Node.removeChild ,
The removed child node still exists in memory, but is no longer part of the DOM. You may reuse the removed node later in your code, via the oldChild object reference.
yaitu pendengar acara mungkin bisa dihapus, tetapi node
masih ada dalam memori.
removeChild
itu. Keduanya juga mengembalikan Anda referensi yang Anda dapat tetap menempel kembali yang terakhir (dalam hal ini jelas tetap dalam memori) atau membuang cara (dalam hal ini akhirnya diambil oleh GC dan dihapus).
Jangan ragu untuk menonton tumpukan untuk melihat kebocoran memori di penangan acara menjaga referensi ke elemen dengan penutupan dan elemen menjaga referensi ke penangan acara.
Pengumpul sampah tidak suka referensi lingkaran.
Kasus kebocoran memori biasa: mengakui suatu objek memiliki referensi ke elemen. Elemen itu memiliki referensi ke pawang. Dan pawang memiliki referensi ke objek. Objek memiliki referensi ke banyak objek lain. Objek ini adalah bagian dari koleksi yang Anda pikir telah Anda buang dengan menghapus referensi dari koleksi Anda. => seluruh objek dan semua yang dirujuk akan tetap ada dalam memori sampai halaman keluar. => Anda harus berpikir tentang metode pembunuhan lengkap untuk kelas objek Anda atau mempercayai kerangka kerja mvc misalnya.
Selain itu, jangan ragu untuk menggunakan bagian Penahan pohon alat dev Chrome.
Hanya memperluas jawaban lain ...
Penangan event yang didelegasikan tidak akan dihapus setelah penghapusan elemen.
$('body').on('click', '#someEl', function (event){
console.log(event);
});
$('#someEL').remove(); // removing the element from DOM
Sekarang periksa:
$._data(document.body, 'events');
Mengenai jQuery
, metode umum berikut juga akan menghapus konstruksi lainnya seperti data dan penangan peristiwa:
Selain elemen itu sendiri, semua acara terikat dan data jQuery yang terkait dengan elemen dihapus.
Untuk menghindari kebocoran memori, jQuery menghapus konstruksi lain seperti data dan penangan peristiwa dari elemen anak sebelum menghapus elemen itu sendiri.
Selain itu, jQuery menghapus konstruksi lain seperti data dan penangan peristiwa dari elemen anak sebelum mengganti elemen-elemen itu dengan konten baru.
Ya, pemulung juga akan membuangnya. Mungkin tidak selalu demikian halnya dengan browser lawas.