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

Liked this article? Support me on Patreon and get direct help from me via a private Slack channel or 1-2-1 mentoring.
Subscribe to my newsletter


Hi, I’m Yan. I’m an AWS Serverless Hero and the author of Production-Ready Serverless.

I specialise in rapidly transitioning teams to serverless and building production-ready services on AWS.

Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.

Hire me.


Check out my new course, Complete Guide to AWS Step Functions. In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. Including basic concepts, HTTP and event triggers, activities, callbacks, nested workflows, design patterns and best practices.

Get Your Copy