很多文章(例如msdn)都说当循环引用涉及DOM对象和JS对象时,在某些浏览器中无法清除循环引用。
(IE 6 根本做不到,IE7 只能在页面请求之间做):
Javascript Native(漏洞):
function leak(){
var elem = document.createElement("DIV");
document.body.appendChild(elem);
elem.onclick = function () {
elem.innerHTML = elem.innerHTML + ".";
// ...
};
}
因为元素的 onload 属性通过闭包引用回自身,它创建了一个循环引用:
elem [DOM] -> elem.onclick [JS] -> elem [DOM]
JQuery 版本(不会泄漏):
function leak(){
var elem = $('<div></div>');
$(document.body).append(elem);
elem.click(function () {
elem.html(elem.html() + ".");
// ...
};
}
在这种情况下,即使仍然存在循环引用,jQuery 也会阻止所有相关浏览器发生泄漏:
elem [JS] -> element [DOM] -> elem.onclick [JS] -> elem [JS]
我的问题:如果仍然存在循环引用,jQuery 如何阻止泄漏?
最佳答案
jQuery 代码中的最后一件事(在 Sizzle 的代码之前,它的选择器引擎)是这个(这是防止泄漏的代码):
// Prevent memory leaks in IE
// Window isn't included so as not to unbind existing unload events
// More info:
// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
if ( window.attachEvent && !window.addEventListener ) {
window.attachEvent("onunload", function() {
for ( var id in jQuery.cache ) {
if ( jQuery.cache[ id ].handle ) {
// Try/Catch is to handle iframes being unloaded, see #4280
try {
jQuery.event.remove( jQuery.cache[ id ].handle.elem );
} catch(e) {}
}
}
});
}
当你在 jQuery 中做任何事情时,它会存储它所做的事情(即函数)和完成的事情(即 DOM 元素)。 onunload 通过 jQuery 缓存从它自己的内部缓存的事件处理程序中删除函数(这是事件存储的地方,而不是在单个 DOM 节点上)。
哦,还有这条线:
if ( window.attachEvent && !window.addEventListener ) {
确保它只在 IE 上运行。
关于javascript - JQuery 垃圾收集——这会干净吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3396264/