JQuery垃圾收集 - 这会干净吗?

Bob*_*mer 15 javascript jquery memory-leaks

许多文章(例如msdn)都说当涉及DOM对象和JS对象时,在某些浏览器中无法清除循环引用.

(IE 6根本无法完成,IE7只能在页面请求之间执行):

Javascript Native(Leaks):

function leak(){
    var elem = document.createElement("DIV");
    document.body.appendChild(elem);
    elem.onclick = function () {
        elem.innerHTML = elem.innerHTML + ".";
        // ...
    };
}
Run Code Online (Sandbox Code Playgroud)

因为元素的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() + ".");
        // ...
    };
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,即使仍有循环引用,jQuery也会阻止所有相关浏览器中发生泄漏:

elem [JS] -> element [DOM] -> elem.onclick [JS] -> elem [JS]

我的问题:如果仍有循环引用,jQuery如何阻止泄漏?

ibl*_*ish 6

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) {}
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

当你在jQuery中做任何事情时,它会存储它所做的事情(即函数)和什么(即DOM元素).onunload通过jQuery缓存从其自己的内部缓存的事件处理程序中移除函数(无论如何都存储事件而不是单个DOM节点).

哦,和行:

if ( window.attachEvent && !window.addEventListener ) {
Run Code Online (Sandbox Code Playgroud)

确保它只在IE上运行.