Javascript中事件中引用的局部函数发生了什么

What happens to local functions referenced in the events in Javascript?

本文关键字:函数 发生了 什么 局部 事件 引用 Javascript      更新时间:2023-09-26

我想我错过了关于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()'的所有事件。在这种情况下,我想它只是'click'事件。javascript会破坏'obj.test()'范围和所有函数,包括匿名函数范围吗?我还需要关心别的什么吗?

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

多谢!

当您使用.off解除点击事件的绑定时,lcky()在运行gc时处于空闲时间,可以由浏览器进行垃圾收集(gc)。在下一行中,您调用了obj.test(),因此此时的obj将无法被垃圾收集,因为您在解除click事件绑定后再次运行了它。lcky()现在被重新定义在一个单独的作用域中,而不是第一次的obj。当Test被调用时,原始的仍然可以被gc,但是新的不能。如果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);
})();

只要#myEl上存在点击事件,adoA就不能被垃圾收集