So what is Closure?

I’m not talking about closure in a relationship :).  I am talking about closure in programming.  I first encountered closure in JavaScript the hard way.  I was debugging for days the following code as to why it was not behaving the way I expect it to be.

var setRowsOnclickEvent = function () {
    var table = $("tableList");
    
    for (var i = 1; i < table.rows.length; i++) {
        var row = table.rows[i];
        
        row.onclick = function () {
            var table = $("tableList");
            
            for (var j = 1; j < table.rows.length; j++) {
                var row = table.rows[j];
                
                if (j == i) {
                    row.className = "selectRow";
                }
                else {
                    row.className = "unselectRow";
                }
            }
        }
    }
}

 

 

The JavaScript function above is setting the onclick event of all the rows in the table.  It iterates through each row in the table and assigns an inline function, an event handler, to the row’s onclick event.  Note that the event handler, or the inner function, uses the loop variable i of the outer function, containing the row number, so that whenever the row is clicked it get’s highlighted.

My mistake was to think that the value of i is passed on to the event handler like a function parameter and placed on the stack.  Don’t make that mistake. The value of i actually closes on you, I mean on the event handler, or the inner function.  So variable i is a closure variable, while the inner function is a closure function.

Again don’t make the mistake that assigning the event handler to the onclick event actually calls the event handler.  It’s an event handler so it can be called even after the outer function has been out of scope.

So you ask, what happens to the value of i then? Well for closure situations like this, the compiler creates a special context object containing the closure variables so that closure functions, when they get executed, will have access to these variables even if the function that the closure variables are declared in are already out of scope.

In the above JavaScript code, what’s happening is whenever any row is clicked, the last row always gets highlighted, so which is to say, the variable i always has the value of the last row number.  The reason is because, again, even if the closure function, or the event handler in our example, is inside a loop that iterates through each row and incrementing the closure variable i, when the loop exits, the closure variable i will contain the last value in the loop which is the last row number and that is the value that the event handler will get when it gets executed at a later time.  So the value of the closure variable i will be the value at runtime and not at capture time, or in our example, not at the time when the event handler is declared and assigned.

Below is my solution to the JavaScript code above.  The solution is to wrap the event handler in another function where I pass in i as a function parameter, thereby forcing the compiler to capture the value of i as it increments itself inside the loop.

var setRowsOnclickEvent = function () {
    var table = $("tableList");
    
    for (var i = 1; i < table.rows.length; i++) {
        var row = table.rows[i];
        
        row.onclick = (function (i) {
            return function () {
                var table = $("tableList");
                
                for (var j = 1; j < table.rows.length; j++) {
                    var row = table.rows[j];
                    
                    if (j == i) {
                        row.className = "selectRow";
                    }
                    else {
                        row.className = "unselectRow";
                    }
                }
            }           
        })(i);
    }
}

 

 

EDIT:  The code above works by making the function (outer function) that wraps the event handler (inner function) as an IIFE (Immediately Invoked Function Expressions).  This creates a scope object for the outer function (remember Javascript scoping stops at the function level while C# continues at the block level) containing the current value of i in the loop which is retained even after the outer function has returned.  Then each row’s onclick event will end up having an inner function with access to a separate outer function’s scope object, each containing a different value of i.

It’s not only the JavaScript language that has closure.  Other languages have it as well, like C#.  I encountered closure in C# the same way I did in JavaScript.  I was declaring/passing in a lambda expression to a function call inside a foreach loop, that references the foreach variable.  And since C# has a slightly different handling of closure than JavaScript, the solution is different.  In C#, one just need to assign the foreach or loop variable to a temporary variable and reference the temporary variable instead.

public void SomeFunction()
{
    // ...
    foreach (Filter filter in filters)
    {
        // have to assign filter value to temp variable in the loop
        //  because the lambda expression we're using here is in a closure
        string filterVal = filter.Value;
        switch (filter.Field)
        {
            case "Location Name":
                locs = locs.Where(l => l.LocationName.Contains(filterVal));
                break;
            // ...
        }
    }
    // ...
}

 

 

It’s not easy to wrap your mind around closure, at least for me.  Closures in C# vs JavaScript – Same But Different really explains it to me clearly, from a really really technical point of view, as in how the compiler handles closure both in C# and JavaScript.  Don’t worry it’s not a long read but one needs to really read through the code. I’ve got other links for further reading if need be:

I can’t guarantee you to become a closure relationship expert, but after going through the readings and links above,  I can guarantee you to become a closure programming expert ;).

Advertisements

2 thoughts on “So what is Closure?

  1. Angelo says:

    I could understand closures in JS, being the difference with the value at declaration/definition of the handler vs at runtime invocation. I’m even surprised at having access to this even after it bec omes out of scope.

    But the CS closures, albeit within a lambda expr or even in LINQ, the scope of the foreach var is active, and is invoked at runtime. It should have captured the current value within the switch stmt. Is this due to the nature of compiler optimizations when both lambdas and outer loops are involved? It seems that the record activation instance (again inferring stacks) should have properly captured the correct values as the code portion was invoked at runtime and not as a delegate definition.

    • It basically just boils down to how these closures are implemented by the language’s compiler. The trick, when dealing with these closures, is to put yourself in the shoes of a compiler designer/developer. So depending on how they implement these closures will determine the behavior.

      To clarify, in both JavaScript and C#, loop variables that are closure variables are scoped at the function level by the compiler. In JavaScript, as far as local variables that are closure variables, whether they are declared inside the loop or curly braces, they are still scoped at the function level. In C# however, it’s different. Apparently local variables declared inside the loop or curly braces are scoped at the loop level or inside the curly braces. That is why in C# you can use a temporary variable to contain the value of the loop variable.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s