JavaScript Closures

Code Morning!

If you have learnt about functions and modules on this blog, learning closures should not be a big deal for you. If you just happen to land here and haven’t gone through those two topics, that is also perfectly fine. Closures fall in the category of advanced JavaScript concepts but trust me, if you know and understand how inner functions work, understanding closures will be a cakewalk.

For all hard working and curious folks here who hate shortcuts and love to dive deep, I will recommend the post on functions before moving on. For those lazy and 2-minutes maggi lovers kinda dudes, this post will make sure you get the required basic concepts cooked and served right to your plate before jumping to main course (closures).

Inner Functions

An inner function is fundamentally a “function within a function”. JavaScript supports nested functions, that means you can create one or more functions inside a function. The inner functions may again contain functions inside and this nesting can go even deeper. Let’s see this with a simple example.

function innerOuterDemo(){
   console.log("The outer function");

   function innerFunction(){
      console.log("The inner function");
   }
   return innerFunction;
}

The function innerOuterDemo contains an inner function named innerFunction that just writes “The inner function” to console. A call to innerOuterDemo will write “The outer function” to console and return the function innerFunction.

var doSomething = innerOuterDemo(); // Logs "The outer function" and returns innerFunction
doSomething(); // Logs "The inner function"

Pretty simple and straightforward. But just keep in mind that once a function finishes the execution and returns, it’s no longer in scope. That says when innerOuterDemo gets executed and returns the innerFunction, innerOuterDemo is no longer in scope.

Now that we have covered basics of function nesting and scope, let’s jump right to closures. Consider the example below.

function foodAndMore(){
   var myFood = "Pizza and Pasta";
 
   function getMyFood(){
      return myFood;
   }
 
   return getMyFood;
}
 
var foodILove = foodAndMore();
console.log("I love " + foodILove());

Quite similar to the first illustration except that we have some data (myFood variable) we are playing with. The variable myFood belongs to the outer function foodAndMore but is used inside inner function getMyFood in return statement. Invocation to foodAndMore function returns getMyFood function which is assigned to variable foodILove. When you run the above snippet, it will write the text “I love Pizza and Pasta” to console.

Now what is special here? Remember my words when I said when a function completes its execution it goes out of scope? If so, shouldn’t myFood variable that contains value “Pizza and Pasta” go out of scope when function foodAndMore returns after execution? But if you have seen the output in console which logs “I love Pizza and Pasta” then this is certainly not the case.

Closure

A closure is the combination of an inner function and variables defined at outer scope but accessible to inner function. In other words, a closure is an inner function that can access outer function’s variables. Now let’s get hungry and take a glance over our foodie example. As we have already observed, the inner function getMyFood has access to outer function’s variable myFood even when outer function has completed its execution and is out of scope. So the combination of function getMyFood and varaible myFood is an example of a closure. We can anytime call getMyFood function through a variable reference (e.g. foodILove) and get the value of myFood variable which is “Pizza and Pasta”.

In JavaScript, inner functions have access not only to the variables of outer functions but also to their parameters. The next example will prove this right.

function getMultiplier(multiplyBy){
   function multiply(num){
      return multiplyBy * num;
   }
 
   return multiply;
}
 
var multiplyByTwo = getMultiplier(2);
var multiplyByTen = getMultiplier(10);
var twoIntoFive = multiplyByTwo(5); // 10
var tenIntoSix = multiplyByTen(6);  // 60

So inner function multiply has access to the outer function’s parameter multiplyBy. Outer function getMultiplier returns a function that can be used as a multiplier function. We are creating two functions multiplyByTwo and multiplyByTen out of it. While invoking any of these two functions, JavaScript runtime remembers the execution environment (arguments to getMultiplier function) and performs the multiplication between the numbers.

Closures are used extensively in JavaScript and JavaScript based libraries and frameworks. Trivial examples are event handling and AJAX calls when you write inline functions as event handler or callbacks. Those inline functions have access to the main (outer) function’s variables and parameters.

Here is an example of a button click event handler function (closure) in jQuery. The function has access to count variable and its state even when outer function is not in execution.

$(function(){
   var count = 1;
   $("#counterBtn").Click(function(){ 
                      alert("Your click count is: " + count++);
                    });
});

Closures are also useful in defining public functions that can access private functions and variables in JavaScript’s popular module pattern. A simple illustration is given below.

var mathUtility = (function(){
   var count = 1;
 
   function increment(number){
      return number + count;
   }
 
   function decrement(number){
      return number - count;
   }
 
   return {
      nextOf: increment,
      previousOf: decrement
   };
}());
 
var numberAfterFive = mathUtility.nextOf(5);       // 6
var numberBeforeTen = mathUtility.previousOf(10);  // 9

I hope the example above is self explanatory. We are creating a module mathUtility that contains two private functions increment and decrement. Both private functions have access to count variable in outer anonymous function, hence forming closures. We return an object, actually a module named mathUtility containing two public functions nextOf and previousOf that can be used to find next or previous numbers of any given number.

Let me not reduce the size of your scrollbar and say the final words. Just remember that JavaScript functions remember their execution environment. JavaScript runtime makes sure that outer function’s variables and parameters that were in scope and accessible to inner functions will always be accessible to inner functions.

I tried to keep this post concise, to the point and easy to understand. Leave your comments if you still have doubts or if you find something that can be improved further. Don’t forget to share with your near and dear ones if you think the post can benefit them. Thanks for reading.

You might also be interested in:

Share This:

Leave a Reply