6

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!

potomok
  • 1,249
  • 3
  • 12
  • 16
  • 2
    This may be of some help in explaining how/why this works: [JavaScript Closures](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work)... – War10ck May 23 '13 at 18:15

1 Answers1

3

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.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • Thanks for your answer. It's clear now! What would you personally recommend for dynamic page loading: to have one javascript file and register all events in advance for all pages (let's say 20 pages for simple mobile quiz game) or to unsubscribe all the events for previous page and subscribe for the current one (not sure how safe it's in practice)? – potomok May 23 '13 at 23:40
  • That depends on what the pages are. It sounds like what you're doing could actually have the same events handle all of the pages – Kevin B May 24 '13 at 00:27