Closure in Javascript vs C#

Java vs C#

As Jon Skeet point­ed out in this excel­lent arti­cle on clo­sures, the strate­gies of cap­tur­ing the exe­cu­tion con­text which the behav­iour is bound to dif­fer­ent between Java and C#. C# cap­tures the vari­able itself, where­as Java cap­tures the val­ue of the vari­able. To illus­trate the dif­fer­ence, here’s Jon’s orig­i­nal exam­ple in C#:

// First build a list of actions
List<Action> actions = new List<Action>();

for (int counter = 0; counter < 10; counter++)
{
    actions.Add(() => Console.WriteLine(counter));
}

// Then execute them
foreach (Action action in actions)
{
    action();
}

This code actu­al­ly writes 10 ten times instead of 0 to 9 because the con­text the actions are bound to is the vari­able counter, and at the time of exe­cu­tion the val­ue of counter is 10 hence why each Action del­e­gate writes 10 instead of the val­ue of counter at the time the Action del­e­gate was cre­at­ed.

The equiv­a­lent code in Java would print 0 to 9 because Java’s clo­sure imple­men­ta­tion cap­tures the val­ue of the vari­able instead.

How­ev­er, as Jon point­ed out, whilst Java’s imple­men­ta­tion is more intu­itive and eas­i­er to under­stand (less WTF bugs), C#‘s imple­men­ta­tion is more flex­i­ble as you can just eas­i­ly mim­ic the effect of cap­tur­ing the variable’s val­ue by using a local vari­able:

// First build a list of actions
List<Action> actions = new List<Action>();

for (int counter = 0; counter < 10; counter++)
{
    int copy = counter;
    actions.Add(() => Console.WriteLine(copy));
}

// Then execute them
foreach (Action action in actions)
{
    action();
}

Javascipt vs C# (Updated 16/01/2011)

Thanks for Jens for point­ing out my ini­tial incor­rect assess­ment (see com­ment), so I revised my test and used a more straight for­ward test using just one pri­vate vari­able:

function test () {
    var i = 10;
    
    // create the closure
    var func = function () { return i; };

    // 10
    alert(func());

    i = 11;
    // 11? or 10?
    alert(func());
}

The test here is sim­ple, we cre­ate a func­tion func which returns the val­ue of the pri­vate vari­able i, whose val­ue is then changed lat­er on. If Javascript cap­tures the val­ue of the vari­able then the sec­ond time func is invoke the alert mes­sage would still be 10, oth­er­wise it’ll be 11 which is the cur­rent val­ue of i.

And the answer is?

.

.

.

Javascript cap­tures the ref­er­ence of the vari­able, and the sec­ond alert mes­sage is 11.

References:

Jon Skeet’s arti­cle on clo­sures

Arti­cle on Javascript clo­sures