JavaScript Closures Explained

If you write any code in JavaScript then you’ve probably used closures, but do you actually understand what they are and how they work?  Taking the time to understand closures and how they’re implemented can add a deeper dimension to your understanding of the JavaScript language.  In this article, I’ll discuss what closures are and how they’re specified for the JavaScript language.

What Are Closures?

A closure is a pairing of a function along with its referencing environment such that identifiers within the function may refer to variables declared within the referencing environment.

Let’s consider the following example:

var createGreeting = function(greeting) {
    return function(name) {
        document.write(greeting + ', ' + name + '.');
    };
};


helloGreeting = createGreeting("Hello");
howdyGreeting = createGreeting("Howdy");

helloGreeting("John");  // Hello, John.
helloGreeting("Sally"); // Hello, Sally.
howdyGreeting("John");  // Howdy, John.
howdyGreeting("Sally"); // Howdy, Sally.

 

In this code, a function named createGreeting is defined which returns an anonymous function.  When the anonymous function is executed, it prints a greeting which consists of the outer function’s greeting parameter along with the inner function’s name parameter.  While the greeting parameter is neither a formal parameter  nor a local variable of the inner function (which is to say it is a free variable), it is still resolved when the function executes.  Moreover, the createGreeting function object is no longer in scope and may have even been garbage collected at the point the function executes.  How then does this work?

The inner function is capable of resolving the greeting identifier due to a closure which has been formed for the inner function.  That is to say, the inner function has been paired with its referencing (as opposed to its calling) environment.

Conceptually, we can think of our closure as the marriage between a function and the environment in which it was declared within:

closure2

 

Exactly what this marriage looks like at an implementation level differs depending on the language.  In C# for instance, closures are implemented by the instantiation of a compiler-generated class which encapsulates a delegate and the variables referenced by the delegate from its declaring scope. In JavaScript, the function object itself contains a non-accessible property pointing to an object containing the variables from its declaring scope.  While each implementation differs, both render a function that has access to what its environment looked like at the point it was created.

Let’s move on to examining how JavaScript closures work from a specification perspective.

JavaScript Closures

To understand how closures work in JavaScript, it helps to have a grasp of the underlying concepts set forth within the ECMAScript Language Specification.  I’ll be using Edition 5.1 (ECMA-262) of the specification as the basis for the following discussion.

Execution Contexts

When a JavaScript function is executed, a construct referred to as an Execution Context is created.  The Execution Context is an abstract concept prescribed by the specification to track the execution progress of its associated code.  As an application runs, an initial Global Execution Context is created.  As each new function is created, new Execution Contexts are created which form an Execution Context stack.

There are three primary components prescribed for the Execution Context:

    1. The LexicalEnvironment

    2. The VariableEnvironment

    3. The ThisBinding

Only the LexicalEnvironment and VariableEnvironment components are relevant to the topic of closures, so I’ll exclude discussion of the ThisBinding.  (For information about how the ThisBinding is used, see sections 10.4.1.1, 10.4.2, and 10.4.3 of the ECMAScript Lanauage Specification.)

LexicalEnvironment

The LexicalEnvironment is used to resolve identifier references made by code associated with the execution context.  Conceptually, we can think of the LexicalEnvironment as an object containing the variables and formal parameters declared within the code associated by the current Execution Context.

A LexicalEnvironement itself is comprised of two components: An Environment Record, which is used to store identifier bindings for the Execution Context, and an outer reference which points to a LexicalEnvironment of the declaring Execution Context (which is null in the case of the Global Execution Context’s LexicalEnvironment outer reference).  This forms a chain of LexicalEnvironments, each maintaining a reference to the outer scope’s environment:

 

LexicalEnvironmentChain

 

VariableEnvironment

The VariableEnvironment is used to record the bindings created by  variables and function declarations within an execution context.  Upon reading that description, you may be thinking: “but I thought the LexicalEnvironment held the bindings for the current execution context”.  Technically, the VariableEnvironment contains the bindings of the variables and function declarations defined within an Execution Context and the LexicalEnvironment is used to resolve the bindings within the Execution Context.  Confused?  The answer to this seemingly incongruous approach is that, in most cases, the LexicalEnvironment and VariableEnvironment are references to the same entity.

The LexicalEnvironment and VariableEnvironment components are actually references to a LexicalEnvironment type.  When the JavaScript interpreter enters the code for a function, a new LexicalEnvironment instance is created and is assigned to both the LexicalEnvironment and VariableEnvironment references.  The variables and function declarations are then recorded to the VariableEnvironment reference.  When the LexicalEnvironment is used to resolve an identifier, any bindings created through the VariableEnvironment reference are available for resolution.

Identifier Resolution

As previously discussed, LexicalEnvironments have an outer reference which, except for the Global Execution Context’s LexicalEnvironment, points to a LexicalEnvironment record of the declaring Execution Context (i.e. a function block’s “parent” scope).  Functions contain an internal scope property (denoted as [[Scope]] by the ECMAScript specification) which is assigned a LexicalEnvironment from the declaring context.  In the case of function expressions (e.g. var doStuff = function() { …}), the [[Scope]] property is assigned to the declaring context’s LexicalEnvironment.  In the case of function declarations (e.g. function doStuff() { … }), the [[Scope]] property is assigned to the declaring context’s VariableEnvironment.  We’ll discuss the reasons for this disparity shortly, but for now let’s just focus on the fact that the function has a [[Scope]] which points to the environment in which is was created.  This is our pairing of a function with its referencing environment, which is to say, this is our closure. 

If we recall our previous conceptualization of a function paired with its environment, the JavaScript version of this conceptualization would look a little like this:

 

closure3

When resolving an identifier, the current LexicalEnvironment is passed to an abstract operation named GetIdentiferReference which checks the current LexicalEnvironment’s Environment Record for the requested identifier and if not found calls itself recursively with the LexicalEnvironment’s outer reference.  Each link of the chain is checked until the top of the chain is reached (the LexicalEnvironment of the Global Context) in which case the binding is resolved or a reference of undefined is returned.

A Distinction Without a Difference … Usually

As mentioned, the LexicalEnvironment and the VariableEnvironement references point to the same LexicalEnvironment instance in most cases.  The reason for maintaining these as separate references is to support the with statement.

The with statement facilitates block scope by using a supplied object as the Environment Record for a newly created LexicalEnvironment.  Consider the following example:

var x = {
    a: 1
};

var doSomething = function() {
    var a = 2;
    
    with(x) {
        console.log(a);
    };
};
doSomething(); // 1

 

In this code, while the doSomething function assigns the variable a the value of 2, the console.log function logs the value of 1 instead of 2.  What is happening here is that, for the enclosing block of code, the with statement is inserting a new LexicalEnvironment at the front of the chain with an Environment Record set to the object x.  When the code within the with statement executes, the first LexicalEnvironment to be checked will be the one created by the with statement whose Environment Record contains a binding of x with the value of 1.  Once the with statement exits, the LexicalEnvironment of the current Execution Context is restored to its previous state.

According to the ECMAScript specification, function expressions may be declared within a with statement, but not function declarations (though most implementations allow it with varied behavior).  Since function expressions may be declared, their declaration should form a closure based upon the declaring environment’s LexicalEnvironment because it is the LexicalEnvironement which might be changed by a with statement.  This is the reason why Execution Contexts are prescribed  two different LexicalEnvironment references and why function declarations and function expressions differ in which reference their [[Scope]] property is assigned upon function creation.

Conclusion

This concludes our exploration of closures in JavaScript.  While understanding the ECMAScript Language Specification in detail certainly isn’t necessary to have a working knowledge of closures, I find taking a peek under the covers now and again helps to broaden one’s understanding about a language and its concepts.

About Derek Greer

Derek Greer is a consultant, aspiring software craftsman and agile enthusiast currently specializing in C# development on the .Net platform.
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1046

  • David Fox

    Thanks! Even as a JavaScript amateur, this was very informative. I’ve been using closures without knowing it.

  • Pingback: JavaScript Closures « ValueType

  • Pingback: In the News: 2012-02-17 | Klaus' Korner

  • http://SelfReliantPress.com/wp mjy

    Good job! I found closures one of the most difficult JavaScript features to explain in my book “JavaScript: Just the Basics – A Primer for the Complete Beginner.” Thanks.

    • http://www.electronicmusic101.com Andrew Turner

      I just purchased your book for my mobile devices.  Thanks for bringing it up.   I have also blogged, tweeted, and posted info about it.  

  • http://www.electronicmusic101.com Andrew Turner

    Thank you for explaining the technical aspects in detail.  Your use of diagrams is particularly helpful.   I have added your rss feed to my google reader collection, and look forward to reading your subsequent posts!

  • Pingback: Good Reads For The Week: 20/02/2012 — Adam Nuttall

  • Pingback: Rounded Corners 332 – What my mom thinks I do /by @assaf

  • http://www.greenanysite.com/ Tal Ater

    Great post! I really enjoyed this one.

  • Shahar Shelly

    Great Post .
    Thanks.

  • Pingback: A geek with a hat » The commonest javascript bug

  • http://alan.360looks.com/ Alan K Fadliawan

    Good job. The diagrams are easily understood and I like how you use the term ‘pairing’. Thanks!

  • William Kiptoon

    OK…..

    But what are closures useful for?

    Don’t get me wrong, I’m certain they can be used for SOMETHING. Heck, if I felt like it, I could re-write all the javascript on my website in the form of closures?

    But why would I want to do that?

    • derekgreer

      My apologies for just getting around to responding. My guess is that if you are doing anything substantial with JavaScript then you have already been using closures. You use closures for hiding state, function creation and composition, implementing the observer pattern, etc. While this article is indeed light on examples, my goal was to provide a more approachable treatment of the topic for those desiring a deeper understanding of JavaScript’s implementation of closures than was available at the time of its writing.

  • Frederick Ancheta

    the diagrams in your technical explanations are very helpful! great work

  • Stingbat

    “A closure is a pairing of a function along with its referencing environment such that identifiers within the function may refer to variables declared within the referencing environment.”

    Huh?? A little too academic!

    • common

      “a closure is the local variables for a function – kept alive after the function has returned,” DONE!!

      • derekgreer

        I appreciate the humor convey here, but also understanding that while some people just want to know what the pedals on the floor do and what the round thing in front of them is used for, others enjoy (and indeed benefit more greatly by) understanding how the engine of the vehicle works.

    • derekgreer

      Yes, this article is a little on the academic side, but as mentioned in another comment, my goal was to provide a more approachable treatment of the topic of JavaScript’s implementation of closures than was available at the time of its writing (which was mostly just the ECMAScript specs themselves).

  • Huh

    What does that mean?

  • David Goldhirsch

    Thank you–very clear.

  • Abhishek Prakash

    I enjoyed reading this article. Crystal clear!!