Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I think I am missing very important thing about 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()          
})

In the scenario above I have defined an object 'obj' and created a method 'test' for this object. Inside the method I have a local function 'y()' that is used by the 'click' event attached to the button. Also the click event is being attached in the anonymous function.

Then I am calling 'test()', unsubscribing 'click' event from the button and calling 'test()' once again. In a result I receive local=12 and local anonymous=13 that is expected.

However I don't understand what javascript does in memory, especially to function 'y()' and anonymous function on each of these steps.

My specific questions are below however I would be very thankful if you can explain the whole flow.

So when I have dettached all the events referencing the first 'obj.test()'. In this case I guess it's only 'click' event. Will javascript destroy 'obj.test()' scope and all functions including anonymous function scope? Do I need to care about something else?

My use case: I am creating the dynamic page loading with different page behaviors so I wanted to separate javascript for each page in the global objects methods and once the new page is loaded, i wanted to detach all the events for the previous page and call the behavior function. But suddenly I realized that I don't really understand how javascript works and potentially there can be really huge memory leaks with this approach. :--)

Many Thanks!

like image 862
potomok Avatar asked May 23 '13 18:05

potomok


1 Answers

When you use .off to unbind the click event, lc, k, and y() are at that point in time free to be garbage collected (gc) by the browser when the gc is ran. On the next line you called obj.test(), so obj at that point will not be able to be garbage collected because you ran it again after unbinding the click event. lc k and y() are now defined again in a separate scope from the first time obj.test was called, the original ones are still free to be gc'd, but the new ones are not. If the click event is then unbound later, lc, k, y(), and obj will no longer be referenced by anything and therefore will be free for the gc.

The above is a little confusing, i'll try to make it clearer.

As long as something inside of obj references something in a scope that is above the scope created by obj.test(), obj will not be garbage collected. While an event is bound due to calling obj.test(), the event handler references variables inside of the obj.test() scope and the element is part of a dom, so obj can't be garbage collected until the event is no longer bound to an element.

Here's an example:

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

As long as that click event exists on #myEl, a and doA can't be garbage collected.

like image 63
Kevin B Avatar answered Oct 12 '22 00:10

Kevin B