6

我想我错过了关于 javascript 的非常重要的事情

var gl = 10
$(document).ready(function() {
    var obj = {}
    obj.test = function() {
        gl++

        var lc = gl
        function y() {
            alert('local = ' + lc)
        }

        (function() {
            var k = lc + 1
            $('#button').click(function() {
                alert('local anonymous = ' + k)
                y()
            })                  
        })();

    }

    obj.test()
    $('#button').off()
    obj.test()          
})

在上面的场景中,我定义了一个对象'obj'并为此对象创建了一个方法'test'。在方法内部,我有一个本地函数 'y()',由附加到按钮的 'click' 事件使用。click 事件也附加在匿名函数中。

然后我调用'test()',从按钮取消订阅'click'事件并再次调用'test()'。结果,我收到了预期的 local=12 和 local anonymous=13 。

但是我不明白 javascript 在内存中的作用,尤其是在每个步骤中的函数 'y()' 和匿名函数。

我的具体问题如下,但如果你能解释整个流程,我将非常感激。

所以当我分离所有引用第一个'obj.test()'的事件时。在这种情况下,我猜这只是“点击”事件。javascript 会破坏 'obj.test()' 范围和包括匿名函数范围的所有函数吗?我需要关心其他事情吗?

我的用例:我正在创建具有不同页面行为的动态页面加载,所以我想在全局对象方法中为每个页面分离 javascript,一旦加载了新页面,我想分离前一页的所有事件并调用行为函数。但突然间我意识到我并不真正了解 javascript 是如何工作的,而且这种方法可能会导致非常大的内存泄漏。:--)

非常感谢!

4

1 回答 1

3

当您用于.off取消绑定单击事件时lck, 和y()在运行 gc 时可以自由地被浏览器进行垃圾收集 (gc)。在您调用的下一行obj.test(),因此obj此时将无法进行垃圾收集,因为您在取消绑定单击事件后再次运行它。lc k并且y()现在在第一次调用 obj.test 时再次在单独的范围内定义,原始的仍然可以自由地被 gc'd,但新的不是。如果 click 事件随后未绑定,lc, k, y(),obj将不再被任何东西引用,因此对于 gc 来说是免费的。

上面有点混乱,我会尽量让它更清楚。

只要里面的obj东西引用了超出创建范围的范围内的东西obj.test()obj就不会被垃圾回收。虽然由于调用而绑定obj.test()了事件,但事件处理程序引用范围内的变量obj.test()并且元素是 dom 的一部分,因此obj在事件不再绑定到元素之前不能被垃圾收集。

这是一个例子:

(function(){
    var a = 1;
    function doA() {
        a++;
    }
    $("#myEl").click(doA);
})();

只要该点击事件存在于 上#myEla并且doA不能被垃圾收集。

于 2013-05-23T18:23:58.180 回答