<p>Apakah pengumpulan sampah JavaScript? Untuk pengaturcara web, memahami kepentingan pengumpulan sampah JavaScript adalah penting untuk menulis kod yang lebih baik. </p>
Ingat bahawa ingatan hanya boleh dituntut semula apabila tiada rujukan aktif kepada objek. Ini adalah perangkap biasa dengan penutupan dan pengendali acara kerana sesetengah enjin JS tidak menyemak pembolehubah yang sebenarnya dirujuk dalam fungsi dalaman dan hanya akan menyimpan semua pembolehubah tempatan bagi fungsi penutup.
Berikut ialah contoh mudah:
function init() {
var bigString = new Array(1000).join('xxx');
var foo = document.getElementById('foo');
foo.onclick = function() {
// 即使`bigString`在任何地方都没有被引用,这可能会创建对`bigString`的闭包!
};
}
Pelaksanaan JS yang naif tidak boleh dikumpulkan semasa pengendali acara wujud bigString。有几种解决这个问题的方法,例如在init()的末尾设置bigString = null(delete对于局部变量和函数参数不起作用: delete从对象中删除属性,而变量对象是不可访问的 - 在严格模式下的ES5甚至会抛出ReferenceError jika anda cuba memadamkan pembolehubah setempat! ).
Saya mengesyorkan cuba mengelakkan penutupan yang tidak perlu jika anda mengambil berat tentang penggunaan memori.
Eric Lippert menulis siaran blog terperinci suatu ketika dahulu yang bercakap tentang topik ini (ditambah membandingkannya dengan VBScript). Untuk lebih tepat, dia menulis tentang JScript, pelaksanaan ECMAScript milik Microsoft sendiri, walaupun sangat serupa dengan JavaScript. Saya rasa anda boleh menganggap bahawa kebanyakan tingkah laku adalah sama dalam enjin JavaScript Internet Explorer. Sudah tentu, pelaksanaan khusus akan berbeza-beza dari penyemak imbas ke penyemak imbas, tetapi saya mengesyaki anda boleh menggunakan beberapa prinsip biasa pada penyemak imbas lain.
Dipetik dari halaman ini:
Tujuan utama kutipan sampah adalah untuk membebaskan pengaturcara daripada perlu risau tentang pengurusan memori objek yang mereka cipta dan gunakan, walaupun sudah tentu kadangkala ini tidak dapat dielakkan - ia sentiasa berfaedah untuk mempunyai sekurang-kurangnya pemahaman umum tentang cara pengumpulan sampah berfungsi.
Nota Sejarah: Versi awal jawapan mempunyai rujukan yang salah kepada pengendali delete. Dalam JavaScript, delete operasi delete运算符的错误引用。在JavaScript中,delete运算符从对象中删除属性,与C/C++中的delete operator memadamkan atribut daripada objek, yang berbeza sepenuhnya daripada delete dalam C/C++.
Berhati-hati dengan rujukan bulat apabila ia berkaitan dengan objek DOM:
Corak Kebocoran Memori dalam JavaScript
Ingat bahawa ingatan hanya boleh dituntut semula apabila tiada rujukan aktif kepada objek. Ini adalah perangkap biasa dengan penutupan dan pengendali acara kerana sesetengah enjin JS tidak menyemak pembolehubah yang sebenarnya dirujuk dalam fungsi dalaman dan hanya akan menyimpan semua pembolehubah tempatan bagi fungsi penutup.
Berikut ialah contoh mudah:
Pelaksanaan JS yang naif tidak boleh dikumpulkan semasa pengendali acara wujud
bigString
。有几种解决这个问题的方法,例如在init()
的末尾设置bigString = null
(delete
对于局部变量和函数参数不起作用:delete
从对象中删除属性,而变量对象是不可访问的 - 在严格模式下的ES5甚至会抛出ReferenceError
jika anda cuba memadamkan pembolehubah setempat! ).Saya mengesyorkan cuba mengelakkan penutupan yang tidak perlu jika anda mengambil berat tentang penggunaan memori.
Eric Lippert menulis siaran blog terperinci suatu ketika dahulu yang bercakap tentang topik ini (ditambah membandingkannya dengan VBScript). Untuk lebih tepat, dia menulis tentang JScript, pelaksanaan ECMAScript milik Microsoft sendiri, walaupun sangat serupa dengan JavaScript. Saya rasa anda boleh menganggap bahawa kebanyakan tingkah laku adalah sama dalam enjin JavaScript Internet Explorer. Sudah tentu, pelaksanaan khusus akan berbeza-beza dari penyemak imbas ke penyemak imbas, tetapi saya mengesyaki anda boleh menggunakan beberapa prinsip biasa pada penyemak imbas lain.
Dipetik dari halaman ini:
Tujuan utama kutipan sampah adalah untuk membebaskan pengaturcara daripada perlu risau tentang pengurusan memori objek yang mereka cipta dan gunakan, walaupun sudah tentu kadangkala ini tidak dapat dielakkan - ia sentiasa berfaedah untuk mempunyai sekurang-kurangnya pemahaman umum tentang cara pengumpulan sampah berfungsi.
Nota Sejarah: Versi awal jawapan mempunyai rujukan yang salah kepada pengendali
delete
. Dalam JavaScript,delete
operasidelete
运算符的错误引用。在JavaScript中,delete
运算符从对象中删除属性,与C/C++中的delete
operator memadamkan atribut daripada objek, yang berbeza sepenuhnya daripadadelete
dalam C/C++.