在Javascript事件中引用的本地函数会发生什么?

时间:2013-05-23 18:09:03

标签: javascript jquery jquery-mobile

我认为我错过了关于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是如何工作的,并且这种方法可能存在巨大的内存泄漏。 : - )

非常感谢!

1 个答案:

答案 0 :(得分:3)

当您使用.off取消绑定点击事件时,lcky()可以在此时免费进行垃圾回收(gc) gc运行时的浏览器。在下一行,您调用了obj.test(),因此此时obj将无法进行垃圾回收,因为您在取消绑定click事件后再次运行它。 lc ky()现在再次定义在与第一次调用obj.test时相同的范围内,原始的仍可以自由gc'd,但是新的不是。如果点击事件稍后解除绑定,则lcky()obj将不再被任何内容引用,因此gc将免费。< / p>

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

只要obj内的某些内容引用范围超出obj.test()创建范围的内容,obj就不会被垃圾回收。当一个事件由于调用obj.test()而绑定时,事件处理程序引用obj.test()范围内的变量,并且该元素是dom的一部分,因此obj不能被垃圾收集,直到事件不再绑定到元素。

以下是一个例子:

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

只要#myEl上存在点击事件,就无法对adoA进行垃圾回收。