Closure in Javascript vs C#

Java vs C#

As Jon Skeet pointed out in this excellent article on closures, the strategies of capturing the execution context which the behaviour is bound to different between Java and C#. C# captures the variable itself, whereas Java captures the value of the variable. To illustrate the difference, here’s Jon’s original example 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 actually writes 10 ten times instead of 0 to 9 because the context the actions are bound to is the variable counter, and at the time of execution the value of counter is 10 hence why each Action delegate writes 10 instead of the value of counter at the time the Action delegate was created.

The equivalent code in Java would print 0 to 9 because Java’s closure implementation captures the value of the variable instead.

However, as Jon pointed out, whilst Java’s implementation is more intuitive and easier to understand (less WTF bugs), C#’s implementation is more flexible as you can just easily mimic the effect of capturing the variable’s value by using a local variable:

// 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 pointing out my initial incorrect assessment (see comment), so I revised my test and used a more straight forward test using just one private variable:

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 simple, we create a function func which returns the value of the private variable i, whose value is then changed later on. If Javascript captures the value of the variable then the second time func is invoke the alert message would still be 10, otherwise it’ll be 11 which is the current value of i.

And the answer is?

.

.

.

Javascript captures the reference of the variable, and the second alert message is 11.

References:

Jon Skeet’s article on closures

Article on Javascript closures


Yan Cui

I’m an AWS Serverless Hero and the author of Production-Ready Serverless. I have run production workload at scale in AWS for nearly 10 years and I have been an architect or principal engineer with a variety of industries ranging from banking, e-commerce, sports streaming to mobile gaming. I currently work as an independent consultant focused on AWS and serverless.

You can contact me via Email, Twitter and LinkedIn.

Hire me.