Understanding JavaScript Closures

In JavaScript, a closure is a function to which the variables of the surrounding context are bound by reference.

function getMeAClosure() {
    var canYouSeeMe = "here I am";
    return (function theClosure() {
        return {canYouSeeIt: canYouSeeMe ? "yes!": "no"}; 
    });
}

var closure = getMeAClosure();
closure().canYouSeeIt; //"yes!"

Every JavaScript function forms a closure on creation. In a moment I’ll explain why and walk through the process by which closures are created. Then I’ll address some common misconceptions and finish with some practical applications. But first a brief word from our sponsors: JavaScript closures are brought to you by lexical scope and the VariableEnvironment

Lexical Scope

The word lexical pertains to words or language. Thus the lexical scope of a function is statically defined by the function’s physical placement within the written source code.

Consider the following example:

var x = "global";

function outer() {
	var y = "outer";	

	function inner() {
		var x = "inner";	
	}
}

Function inner is physically surrounded by function outer which in turn is wrapped by the global context. We have formed a lexical hierarchy:

global
    outer
         inner

The outer lexical scope of any given function is defined by its ancestors in the lexical hierarchy. Accordingly, the outer lexical scope of function inner comprises the global object and function outer.

VariableEnvironment

The global object has an associated execution context. Additionally every invocation of a function establishes and enters a new execution context. The execution context is the dynamic counterpart to the static lexical scope. Each execution context defines a VariableEnvironment which is a repository for variables declared by that context. (ES 5 10.4, 10.5)

[Note in EcmaScript 3, the VariableEnvironment of a function was known as the ActivationObject – which is also the term I used in some older articles]

We could represent the VariableEnvironment with pseudo-code…

//variableEnvironment: {x: undefined, etc.};
var x = "global";
//variableEnvironment: {x: "global", etc.};

function outer() {
	//variableEnvironment: {y: undefined};
	var y = "outer";
	//variableEnvironment: {y: "outer"};

	function inner() {
		//variableEnvironment: {x: undefined};
		var x = "inner";	
		//variableEnvironment: {x: "inner"};
	}
} 

However, it turns out this is only part of the picture. Each VariableEnvironment will also inherit the VariableEnvironment of its lexical scope. [The hero enters (stage-left)….]

The [[scope]] property

When a given execution context encounters a function definition in the code, a new function object is created with an internal property named [[scope]] (as in lexical scope) which references the current VariableEnvironment. (ES 5 13.0-2)

Every function gets a [[scope]] property, and when the function is invoked the value of the scope property is assigned to the outer lexical environment reference (or outerLex) property of its VariableEnvironment. (ES 5 10.4.3.5-7) In this way, each VariableEnvironment inherits from the VariableEnvironment of its lexical parent. This scope chaining runs the length of the lexical hierarchy starting from the global object.

Let’s see how our pseudo-code looks now:

//VariableEnvironment: {x: undefined, etc.};
var x = "global";
//VariableEnvironment: {x: "global", etc.};

function outer() {
	//VariableEnvironment: {y: undefined, outerLex: {x: "global", etc.}};
	var y = "outer";	
	//VariableEnvironment: {y: "outer", outerLex: {x: "global", etc.}};

	function inner() {
		//VariableEnvironment: {x: undefined, outerLex: {y: "outer", outerLex: {x:"global", etc.}};
		var x = "inner";	
		//VariableEnvironment: {x: "inner", outerLex: {y: "outer", outerLex: {x:"global", etc.}};
	}
} 
The [[scope]] property acts as a bridge between nested VariableEnvironments and enables the process by which outer variables are embedded by inner VariableEnvironments (and prioritized by lexical proximity). The [[scope]] property also enables closures, since without it the variables of an outer function would be dereferenced and garbage collected once the outer function returned.

 
So there we have it – closures are nothing but an unavoidable side-effect of lexical scoping πŸ˜‰

Dispelling the Myths

Now that we know how closures work, we can begin to address some of the more scurrilous rumors associated with them.

Myth 1. Closures are created only after an inner function has been returned

When the function is created, it is assigned a [[scope]] property which references the variables of the outer lexical scope and prevents them from being garbage collected. Therefore the closure is formed on function creation

There is no requirement that a function should be returned before it becomes a closure. Here’s a closure that works without returning a function:

var callLater = function(fn, args, context) {
    setTimeout(function(){fn.apply(context, args)}, 2000);
}

callLater(alert,['hello']); 

 
Myth 2. The values of outer variables get copied or “baked in” to the closure

As we’ve seen, the closure references variables not values.

//Bad Example
//Create an array of functions that add 1,2 and 3 respectively 
var createAdders = function() {
    var fns = [];
    for (var i=1; i<4; i++) { 
		fns[i] = (function(n) {
			return i+n;
		});
	}
	return fns;
}

var adders = createAdders();
adders[1](7); //11 ??
adders[2](7); //11 ??
adders[3](7); //11 ??

All three adder functions point to the same variable i. By the time any of these functions is invoked, the value of i is 4.

One solution is to pass each argument via a self invoking function. Since every function invocation takes place in a unique execution context, we guarantee the uniqueness of the argument variable across successive invocations.

//Good Example
//Create an array of functions that add 1,2 and 3 respectively 
var createAdders = function() {
    var fns = [];
    for (var i=1; i<4; i++) { 
		(function(i) {
		    fns[i] = (function(n) {
			    return i+n;
		    });
		})(i)    
	}
	return fns;
}

var adders = createAdders();
adders[1](7); //8 (-:
adders[2](7); //9 (-:
adders[3](7); //10 (-:

 
Myth 3. Closures only apply to inner functions

Admittedly closures created by outer functions are not interesting because the [[scope]] property only references the global scope, which is universally visible in any case. Nevertheless its important to note that the closure creation process is identical for every function, and every function creates a closure.
 
Myth 4. Closures only apply to anonymous functions

I’ve seen this claim in one too many articles. Enough said πŸ˜‰
 
Myth 5. Closures cause memory leaks

Closures do not of themselves create circular references. In our original example, function inner references outer variables via its [[scope]] property, but neither the referenced variables or function outer references function inner or its local variables.

Older versions of IE are notorious for memory leaks and these usually get blamed on closures. A typical culprit is a DOM element referenced by a function, while an attribute of that same DOM element references another object in the same lexical scope as the function. Between IE6 and IE8 these circular references have been mostly tamed.

Practical Applications

Function templates

Sometimes we want to define multiple versions of a function, each one conforming to a blueprint but modified by supplied arguments. For example, we can create a standard set of functions for converting units of measures:

function makeConverter(toUnit, factor, offset) {
	offset = offset || 0;
	return function(input) {
		return [((offset+input)*factor).toFixed(2), toUnit].join(" ");  
	}
}	

var milesToKm = makeConverter('km',1.60936);
var poundsToKg = makeConverter('kg',0.45460);
var farenheitToCelsius = makeConverter('degrees C',0.5556, -32);

milesToKm(10); //"16.09 km"
poundsToKg(2.5); //"1.14 kg"
farenheitToCelsius(98); //"36.67 degrees C"

If, like me, you’re into functional abstraction the next logical step would be to currify this process (see below).

Functional JavaScript

Aside from the fact that JavaScript functions are first class objects, functional JavaScript’s other best friend is closures.

The typical implementations of bind, curry, partial and compose all rely on closures to provide the new function with a reference to the original function and arguments.

For example, here’s curry:

Function.prototype.curry = function() {
    if (arguments.length<1) {
        return this; //nothing to curry with - return function
    }
    var __method = this;
    var args = toArray(arguments);
    return function() {
        return __method.apply(this, args.concat([].slice.apply(null, arguments)));
    }
}

And here’s our previous example re-done using curry

function converter(toUnit, factor, offset, input) {
    offset = offset || 0;
    return [((offset+input)*factor).toFixed(2), toUnit].join(" ");  
}

var milesToKm = converter.curry('km',1.60936,undefined);
var poundsToKg = converter.curry('kg',0.45460,undefined);
var farenheitToCelsius = converter.curry('degrees C',0.5556, -32);

milesToKm(10); //"16.09 km"
poundsToKg(2.5); //"1.14 kg"
farenheitToCelsius(98); //"36.67 degrees C"

There are plenty of other nifty function modifiers that use closures. This little gem comes courtesy of Oliver Steele

/**
 * Returns a function that takes an object, and returns the value of its 'name' property
 */
var pluck = function(name) {
	return function(object) {
		return object[name];
	}
}

var getLength = pluck('length');
getLength("SF Giants are going to the World Series!"); //40

The module pattern

This well known technique uses a closure to maintain a private, exclusive reference to a variable of the outer scope. Here I’m using the module pattern to make a “guess the number” game. Note that in this example, the closure (guess) has exclusive access to the secretNumber variable, while the responses object references a copy of the variable’s value at the time of creation.

var secretNumberGame = function() {
    var secretNumber = 21;

    return {
        responses: {
            true: "You are correct! Answer is " + secretNumber,
            lower: "Too high!",
            higher: "Too low!"
        },

        guess: function(guess) {
            var key = 
                (guess == secretNumber) ||
                    (guess < secretNumber ? "higher": "lower");
            alert(this.responses[key])
        }
    }
}

var game = secretNumberGame();
game.guess(45); //"Too high!"
game.guess(18); //"Too low!"
game.guess(21); //"You are correct! Answer is 21"

Wrap up

In programming terms, closures represent the height of grace and sophistication. They make code more compact, readable and beautiful and promote functional re-use. Knowing how and why closures work eliminates the uncertainty around their usage. I hope this article helps in that regard. Please feel free to comment with questions, thoughts or concerns.

Further Reading

ECMA-262 5th Edition
10.4 Creating the VariableEnvironment
10.4.3.5-7 Referencing the [[scope]] property in the VariableEnvironment
10.5 Populating the VariableEnvironment
13.0-2 Assigning the [[scope]] property when a function is created

50 thoughts on “Understanding JavaScript Closures

  1. Pingback: Twitted by RobLL
  2. >>The closure is created in two stages

    Formally, a closure (a combination of a function code and the parent lexical environment, i.e. that exactly a function object is) is formed at the function’s creation. The function then may never be called in future, but the parent environment is already saved, already closured, i.e. it isn’t garbage collected.

    I.e. when an inner function is returned, it already (theoretically, and practically in some implementations, e.g. Rhino) may access closured data without any execution:

    // form a closure
    var foo = (function () {
      var x = 10;
      return function () {};
    })();
    
    // and access a closured variable,
    // without activation of "foo"
     alert(foo.__parent__.x); // 10

    And what is formed at activation of foo is already its own environment, which may access the parent (closured) environment. At this stage only a correct structure is formed (with saving outer reference in the own environment) in order to access the parent’s data. But the fact of the closure is made at creation.

    >>Admittedly closures created by outer functions are not interesting because the [[scope]] property only references the global scope, which is universally visible in any case.

    Such global functions are interesting from the demonstrating of the again lexical scope (that exactly a requirement for closures) . You may show, that a normal global function is also a closure, since it uses lexically saved (but not dynamically formed, i.e. the environment of a caller) environment in the identifier resolution:

    // global "x"
    var x = 10;
     
    // global function
    function foo() {
      console.log(x);
    }
     
    (function (funArg) {
     
      // local "x"
      var x = 20;
     
      // there is no ambiguity,
      // because we use global "x",
      // which was statically saved in
      // [[Scope]] of the "foo" function,
      // but not the "x" of the caller's scope,
      // which activates the "funArg"
     
      funArg(); // 10, but not 20
     
    })(foo); // pass "down" foo as a "funarg"

    This example relates for “downward funarg problem”, when a function is passed a an argument (as a “funarg”). And this is the one of the reasons why closures where created — to distinguish a dynamic scope from the static (lexical) one.

    >>The solution is to pass each argument via a self invoking function

    You may want to notice, that this is just a one of the solutions. At least there are 4-5 alternative solutions: while, saving as properties of objects, Mozilla’s let, etc (some even without forming an additional object in the scope chain).

    Dmitry.

    P.S.: It’s good that you already use the new terminology of environments (actually, the general concept from the common theory).

    In addition — Chapter 6. Closures.

    1. Nice input Dmitry. Also I am relieved that you are generally in agreement with my article πŸ˜‰ (Most of what I wrote about closures is contrary to the literature I have read – so your endorsement of my general approach is important to me)

      1. @Angus Croll, When fn object is created [[scope]] property will be added in scope chain. Also when fn is invoked activation object with fn agrs, & local variables will be added in scope chain.

        As per explanation of Nicholas Zakas , activation object has high priority as compared to lexical scope property for property lookup.

        In above example funArg() is called in context of window object and it returns window.x value which is 10. That is quite obvious…

        Correct me if I understood wrong ??

  3. Superb article Angus, and very good input from Dmitry as well. Really helped solidify my understanding of closures – I didn’t know about internal [[Scope]] property until now. Thank you!

  4. As always, a nice article with a refreshing point of view. I would like highlight the following paragraph

    The word lexical pertains to words or language. Thus the lexical scope of a function is statically defined by the function’s physical placement within the written source code.

    There are many places where this idea isn’t so clearly expressed.

  5. allright, about the closures, how this get resolved:

    function Thunderbolt(intensity, startEnergy, rate) {
        //private
        var rateEnergyLoose = rate || 1,
            baseEnergy = startEnergy || 100,
            ready = false;
        function checkEnergy() {
            return baseEnergy > 0;
        }
        //this function intends to be privated and access public stuff
        //it needs to change a public value, but can only be call in a private context
        function decreaseEnergy(obj) {
            baseEnergy -= rateEnergyLoose * obj.strength;
        }
    
        //building the object that will be bind to the closure
        return {
            strength : intensity,
            fires : function (target) {
                  if (!ready) { return;}
                  if (target.hit) { 
                      target.hit(strength); //this are not visible here
                 }
                  ready = false;
                  decreaseEnergy(this);
                  chargeUp(); //this are not visible here
            },
            chargeUp: function (p) {
                  var loadTime = p || 40;
                  if (ready){
                      return "already loaded";
                  }
    
                  if (!checkEnergy()) {
                       return "it's empty";
                  }
                  
                  function recharge () {
                      if (loadTime <= 0) {
                          ready = true;
                          decreaseEnergy(...); //was a bad try
                          return "loaded";
                      };
                      loadTime--;
                      setTimeout(this,100);
                  }
     
                  setTimeout(recharge,100);
            }
        };
    };
    

    So, to resolve the private member access to public, i did the follow, but the closure wont let me work nicely in public access. How to workaround that?

    function Thunderbolt(intensity, startEnergy, rate) {
        //private
        var rateEnergyLoose = rate || 1,
            baseEnergy = startEnergy || 100,
            ready = false,
            checkEnergy = function () {
                return baseEnergy > 0;
           },
       
        function decreaseEnergy(obj) {
            baseEnergy -= rateEnergyLoose * obj.strength;
        }
         late = {
            strength : intensity,
            fires : function (target) {
                  if (!ready) { return;}
                  if (target.hit) { 
                      target.hit(strength); //still broken
                 }
                  ready = false;
                  decreaseEnergy(this);
                  //will work this out of this
                  chargeUp(); //this are not visible here
            },
            chargeUp: function (p) {
                  var loadTime = p || 40;
                  if (ready){
                      return "already loaded";
                  }
    
                  if (!checkEnergy()) {
                       return "it's empty";
                  }
                  
                  function recharge () {
                      if (loadTime <= 0) {
                          ready = true;
                          decreaseEnergy(); //now it has access
                          return "loaded";
                      };
                      loadTime--;
                      setTimeout(this,100);
                  }
     
                  setTimeout(recharge,100);
            }
        };
        function decreaseEnergy(obj) {
            baseEnergy -= rateEnergyLoose * late.strength; //it seems ok
        } 
    
        return late;
    };
    

    Sorry for the bad english

    1. On the other hand, may perhaps be interesting to consider this version of ChargeUp. Your asynchronous loop has no body:

        function chargeUp(loadTime) {
          if (ready){return "already loaded";}
          if (!checkEnergy()) {return "it's empty";}
          loadTime = loadTime || 40;
      	setTimeout( function(){
                 ready=true;
                decreaseEnergy();
                //return "loaded"; a return from the event loop 
                //                                  goes with Saito and Cobb!
            },loadTime*100);
        }
      
  6. I have tried homogenize the methods:

    function Thunderbolt(intensity, startEnergy, rate) {
    
      var rateEnergyLoose = rate || 1,
          baseEnergy = startEnergy || 100,
          ready = false;
    
      function checkEnergy() {
         return baseEnergy > 0;
      }
      function decreaseEnergy() {//Unique use of thisThunder
        baseEnergy -= rateEnergyLoose * thisThunder.strength;
      }
      function fires(target) {
        if (!ready) { return;}
        if (target.hit) {target.hit(strength);}
        ready = false;
        decreaseEnergy();
        chargeUp();
      }
      
      function chargeUp(loadTime) {
        var loadTime = loadTime || 40;
        if (ready){return "already loaded";}
        if (!checkEnergy()) {return "it's empty";}
        function recharge () {
          if (loadTime <= 0) {
            ready = true;
            decreaseEnergy();
            return "loaded";
          };
          loadTime--;
          setTimeout(recharge,100);
        }
        setTimeout(recharge,100);
      }
    
      var thisThunder = {
        strength : intensity,//Only used by private method decreaseEnergy
       //Publish public methods
        fires : fires,
       chargeUp : chargeUp
      };
      
      return thisThunder;
    };
    
    1. @Mike @Jose

      I like the way Jose’s returns thisThunder object referencing public functions. Clean.
      More on this later…I need to study the code – (sorry been really busy)

      1. There is an error in fires. Here is the correction

          function fires(target) {
            if (!ready) { return;}
            if (target.hit) {target.hit(thisThunder.strength);}
            ready = false;
            decreaseEnergy();
            chargeUp();
          }
        

        As fires also is a public method , the code below is also valid

          function fires(target) {
            if (!ready) { return;}
            if (target.hit) {target.hit(this.strength);}
            ready = false;
            decreaseEnergy();
            chargeUp();
          }
        
  7. @joseanpg This is great – you tidied up Mike’s original code big time

    chargeUp doesn’t appear to actually make base energy grow (as you pointed out)
    Also why do we want recharge to fail if there is no energy left?

    Finally I think recharge can be self invoking – doesn’t need a timeout to invoke

    or just do this (I think its cleaner)

    function chargeUp(loadTime) {
      var loadTime = loadTime || 40;
      if (ready) {
        return "already loaded";}
      }
      if (!checkEnergy()) {
        return "it's empty"; //but so what? (-:
      }
      recharge();
      function recharge () {
        if (loadTime <= 0) {
          ready = true;
          decreaseEnergy();
          return "loaded";
        };
        loadTime--;
        setTimeout(recharge,100);
      }
    }
  8. @Angus Croll
    the chargeUp method is to reload the thunderbolt. So, the last time that it fires, the chargeUp return that it’s empty.

    @joseanpg
    I prefer your first correction in the chargeUp method for the default assignment. It really doesn’t need the var statement and it’s better to come after the checks. I will stick with that. I really liked the way to declare functions and make it public in the object literal. thanks.

    I did this just to test the closures, and now i think it’s a little senseless.

    I really like the improvements in the code.
    And just after I commented here, I found out that this is bound to the object in a object literal statement. But i didn’t knew if it’s the way it is specified.

    Now i saw the joseanpg’s code, i’m more confident that is the right way. (jsLint also does not complain about that).

    i think the anonimous function is more elegant in the asynchronous loop.

    But the Angus’ loop actualy does count right and i will stick with that.

    joseanpg’s and mine’s, counts 41 secs instead of 40. (we could change the logic statement ( loadTime >= 0) to ( loadTime > 1), but it will impossible to chargeUp instantly.)

    Thank you all for the tips. It’s very difficult to find people who knows javascript as a real programming Language. i’m very glad i found this blog. =]

    My only doubt remaining is about the private method accessing the public attribute. I still think that may exist a better way to do this.

    Thanks again. Sorry for the bad english.

  9. nice article..
    The guess game has an error though !
    var key = (guess==secret) || (guess<secret ? "lower":"higher");
    because the conditional operator returns the first value if the condition holds true and returns the value after the colon if the condition is false πŸ™‚

  10. Hi Angus,
    Thank you for a detailed explanation on closures.I have just started with javascript and find your blog quite useful.
    I have a doubt and was hoping you could help me with it.
    In the GOOD Example in MYTH 2 you have used (i) at the end of the for loop. can you please explain why is (i) used there? what purpose does it serve?

  11. var callLater = function(fn, args, context) {
    // args is accessible via closure to the anonymous function that is called when timeout is triggered.
    // context is undefined within the anonymous function so I don’t know why it was included
    // in argument list.
    // Original sample used the commented out setTimeout code and I don’t know why they used
    // apply since context is undefined.
    // setTimeout(function(){fn.apply(context, args)}, 2000);
    // This seems to work just as well.
    setTimeout(function(){fn(args)}, 2000);
    }
    callLater(alert,[‘hello’]);

  12. Very good article, however I prefer OOP approach far more than closures, which produce bunch of copies of the same function that differs only in parameter (outer, not direct argument). In my opinion it violates the notion of what function actually is. Here’s how I would write a converter example:

    function Converter(unit, factor, offset) {
    this.unit = unit;
    this.factor = factor;
    this.offset = offset || 0;
    }

    Converter.prototype = {
    calculate: function(v) {
    return [((this.offset + v) * this.factor).toFixed(2), this.unit].join(‘ ‘);
    }
    };

    var milesToKm = new Converter(‘km’, 1.60936);
    var poundsToKg = new Converter(‘kg’,0.45460);
    var farenheitToCelsius = new Converter(‘degrees C’,0.5556, -32);

    console.log(milesToKm.calculate(10));
    console.log(poundsToKg.calculate(2.5));
    console.log(farenheitToCelsius.calculate(98));

    I believe it’s more readable, testable, reusable, maintanable. One may say: ok, you are not duplicating the functions, but instead create the same number of objects. That’s correct, but I copy the data (which are different for each object) and not functionality (which is same for all objects).

  13. Very good article, however I prefer OOP approach far more than closures, which produce bunch of copies of the same function that differs only in parameter (outer, not direct argument). In my opinion it violates the notion of what function actually is. Here’s how I would write a converter example:

    function Converter(unit, factor, offset) {
    this.unit = unit;
    this.factor = factor;
    this.offset = offset || 0;
    }

    Converter.prototype = {
    calculate: function(v) {
    return [((this.offset + v) * this.factor).toFixed(2), this.unit].join(‘ ‘);
    }
    };

    var milesToKm = new Converter(‘km’, 1.60936);
    var poundsToKg = new Converter(‘kg’,0.45460);
    var farenheitToCelsius = new Converter(‘degrees C’,0.5556, -32);

    console.log(milesToKm.calculate(10));
    console.log(poundsToKg.calculate(2.5));
    console.log(farenheitToCelsius.calculate(98));

    I believe it’s more readable, testable, reusable, maintanable. One may say ok, you are not duplicating the functions but instead create the same number of objects. That’s correct but I copy the data (which is different for each object) and not functionality (which is same for all objects).

  14. hey in ur explained each execution context has variable environment.But in your sample code you write 2 environentvarable
    function outer() {
    1=> //VariableEnvironment: {y: undefined, outerLex: {x: “global”, etc.}};
    var y = “outer”;
    1=>2 //VariableEnvironment: {y: “outer”, outerLex: {x: “global”, etc.}};.Why is that

Leave a reply to Angus Croll Cancel reply