JavaScript Closures VS. Anonymous Functions

JavaScript closures vs. anonymous functions

Editor's Note: All functions in JavaScript are closures as explained in this post. However we are only interested in identifying a subset of these functions which are interesting from a theoretical point of view. Henceforth any reference to the word closure will refer to this subset of functions unless otherwise stated.

A simple explanation for closures:

  1. Take a function. Let's call it F.
  2. List all the variables of F.
  3. The variables may be of two types:

    1. Local variables (bound variables)
    2. Non-local variables (free variables)
  4. If F has no free variables then it cannot be a closure.
  5. If F has any free variables (which are defined in a parent scope of F) then:

    1. There must be only one parent scope of F to which a free variable is bound.
    2. If F is referenced from outside that parent scope, then it becomes a closure for that free variable.
    3. That free variable is called an upvalue of the closure F.

Now let's use this to figure out who uses closures and who doesn't (for the sake of explanation I have named the functions):

Case 1: Your Friend's Program

for (var i = 0; i < 10; i++) {
(function f() {
var i2 = i;
setTimeout(function g() {
console.log(i2);
}, 1000);
})();
}

In the above program there are two functions: f and g. Let's see if they are closures:

For f:

  1. List the variables:

    1. i2 is a local variable.
    2. i is a free variable.
    3. setTimeout is a free variable.
    4. g is a local variable.
    5. console is a free variable.
  2. Find the parent scope to which each free variable is bound:

    1. i is bound to the global scope.
    2. setTimeout is bound to the global scope.
    3. console is bound to the global scope.
  3. In which scope is the function referenced? The global scope.

    1. Hence i is not closed over by f.
    2. Hence setTimeout is not closed over by f.
    3. Hence console is not closed over by f.

Thus the function f is not a closure.

For g:

  1. List the variables:

    1. console is a free variable.
    2. i2 is a free variable.
  2. Find the parent scope to which each free variable is bound:

    1. console is bound to the global scope.
    2. i2 is bound to the scope of f.
  3. In which scope is the function referenced? The scope of setTimeout.

    1. Hence console is not closed over by g.
    2. Hence i2 is closed over by g.

Thus the function g is a closure for the free variable i2 (which is an upvalue for g) when it's referenced from within setTimeout.

Bad for you: Your friend is using a closure. The inner function is a closure.

Case 2: Your Program

for (var i = 0; i < 10; i++) {
setTimeout((function f(i2) {
return function g() {
console.log(i2);
};
})(i), 1000);
}

In the above program there are two functions: f and g. Let's see if they are closures:

For f:

  1. List the variables:

    1. i2 is a local variable.
    2. g is a local variable.
    3. console is a free variable.
  2. Find the parent scope to which each free variable is bound:

    1. console is bound to the global scope.
  3. In which scope is the function referenced? The global scope.

    1. Hence console is not closed over by f.

Thus the function f is not a closure.

For g:

  1. List the variables:

    1. console is a free variable.
    2. i2 is a free variable.
  2. Find the parent scope to which each free variable is bound:

    1. console is bound to the global scope.
    2. i2 is bound to the scope of f.
  3. In which scope is the function referenced? The scope of setTimeout.

    1. Hence console is not closed over by g.
    2. Hence i2 is closed over by g.

Thus the function g is a closure for the free variable i2 (which is an upvalue for g) when it's referenced from within setTimeout.

Good for you: You are using a closure. The inner function is a closure.

So both you and your friend are using closures. Stop arguing. I hope I cleared the concept of closures and how to identify them for the both of you.

Edit: A simple explanation as to why are all functions closures (credits @Peter):

First let's consider the following program (it's the control):

lexicalScope();
function lexicalScope() { var message = "This is the control. You should be able to see this message being alerted.";
regularFunction();
function regularFunction() { alert(eval("message")); }}

Can anyone explain the difference between closure and anonymous functions?

Have you seen this article? http://www.jibbering.com/faq/faq_notes/closures.html

This could also be good as a starting point: http://www.javascriptkit.com/javatutors/closures.shtml

What is the difference between a closure and an anonymous function in JS

The closure mechanism applies to all JavaScript functions, whether anonymous or not.

I think confusion between the two concepts comes from use of the term "closure" where an author has said something like "the following code creates a closure" and then given an example that happens to use an anonymous function. In such instances typically the closure mechanism is what is important to make the particular piece of code work as intended, while use of an anonymous function rather than a named function just happens to be a convenient way to code it. People reading such examples and seeing "closure" for the first time then misinterpret the term and go on to use it incorrectly in their own Stack Overflow or blog posts and so the confusion spreads.

Is a Java lambdas equivalent to a JavaScript closures?

They are "slightly different" and also "roughly equivalent".

tldr; a Java lambda that access an outer-scoped variable1 is also a closure; and a JavaScript "closure" that does not access an outer-scope variable is not strictly a closure (and can be more precisely called an anonymous function2).


In JavaScript, a closure generally implies "being able to re-assign variables in the outer scope" - however, having access to or "closing over / binding" a variable is sufficient for an anonymous function to be a closure3.

Java lambda's requires that all variables from the outer scope accessed in a lambda are effectively final which means they cannot be re-assigned.

1The rule is that a [Java] lambda expression can only access local variables from an enclosing scope that are effectively final. An effectively final variable is never modified—it either is or could be declared as final - http://www.informit.com/articles/article.aspx?p=2303960

However, since a Java lambda can capture a read-only variable binding to mutable objects, it is possible for a Java lambda to indirectly modify state in the outer context and can thus emulate the ability to "re-assign" values.

2In computer science, a closure is a function that has an environment of its own. Inside this environment, there is at least one bound variable [and] anonymous functions are sometimes wrongly called closures. This is probably because most languages [eg. JavaScript] that have anonymous functions also have closures and it's common for programmers to learn about both at the same time. - https://simple.wikipedia.org/wiki/Closure_(computer_science)

Java also has different semantics on this inside a lambda vs a JS anon-function / closure; also see JavaScript "arrow functions" which have different rules than traditional anonymous functions on how this behaves.


3 Trivial argument:

  • Haskell has closures.
  • Haskell does not allow variables to be re-assigned.
  • Therefore, re-assignment (or mutability) is not a requirement of closures.

Scope and maintainance of variable state in self invoking anonymous function vs anonymous functions

Every time the main body of the outer function is executed and the lines:

var a=2;
var myprivatefunction = function () {
// ...

are run, a new binding for those variables are created in memory.

With the self-invoking function, since it's executed immediately and once, there then exists one binding for the a variable, which the mypublicfunction property can see via the closure.

In contrast, with your nonSelfInvokingAnonymousFunction, every time you invoke it, you create a separate binding for a:

nonSelfInvokingAnonymousFunction().mypublicfunction(); //a is 2
// ^^^ creates an a ^^^^
nonSelfInvokingAnonymousFunction().mypublicfunction(); //a is 2
// ^^^ creates a SEPARATE a ^^^^

When you have two separate bindings for the a variable, calling mypublicfunction on a function that closes over one of the bindings will have no effect on the other binding.

In your last code, when you do

var temp = nonSelfInvokingAnonymousFunction();
// ^^^ creates an a ^^^^
temp.mypublicfunction() ; // a is 4
temp.mypublicfunction(); // a is 6

You create a single a, and a temp whose mypublicfunction function closes over that one a, so calling mypublicfunction multiple times results in that a changing multiple times.



Related Topics



Leave a reply



Submit