Closure – I

The closure “was” and has been one of the most interesting and important concepts of Javascript. I have written “was” because, now that most of the “new” developers are using ES6 and maybe ES7, they might never come across the concept of what closure is and its usage.

For those who are or end up writing ES5 JavaScript code, I am going to explain a bit about the closure. I will use ES5 codes and concepts in this article and, unless I do not mention it, the reader should not apply the ES6 concepts in the examples given this post.

To understand the concept of closure, we first need to understand how scope works in JavaScript. The scope, in general, is defined as the lifespan of a variable in programming languages. In other words, if you create a variable, the scope of that variable determines the scope.

A simple example would be, if you create a variable foo in one of the JS files at the top (the first line of the file), you can use foo in the entire file. Variables declared in such a a way are often referred to have global or window scope, because they can be accessed in the entire file and in all the files included after this one.

Global or window scope is the top level scope.

Every function or variable we create inside a JavaScript file remains in the global scope. When we include this file in our webpage using script tag, these functions and variables will be attached to the window object, i.e. the global scope. So, let’s say, we have a function that can change something in our application and that’s available in the global scope. Anyone with little knowledge the developer tools of a browser can execute those functions. That’s not the right thing for your application. One good example would be, a function that can let’s say, submit an API call and make some changes in the data of the application.

To prevent such actions, we need to make our functions or variables inaccessible from the global scope. In other words, we need to create a scope of our own.

Consider this example:

var x = 10;
function foo () {
    var x = 20;
    return x;
}
console.log (x);           // prints 10
var fooX = foo();
console.log (fooX);        // prints 20

In line 1, we have set the value of x to 10 and on line 3 we have set the value to 20. But as the x at line 3 is inside the function foo and line 3 will only be executed when we invoke the function foo, the x at line 3 and x at line 1 are not the same. And that’s how we shield something from global scope. But hang on for a bit, isn’t foo is global. We can create another function, and create this foo function inside [click here for detailed usage].

Let’s rewrite this example with different variables:

var x = 10;
function foo () {
    var y = 20;
    return y;
}

console.log (x);        // prints 10
console.log (y);        // Reference Error: y is not defined
var fooX = foo();
console.log (fooX);

We have just replaced the x of line 3 with y and added another console log for y. If we run this snippet, we would see that there is reference error which says y is not defined.

It is also important to note that the execution in the above code snippet stops as soon as there is an error. It happens because JavaScript is an interpreted language.

From example 1 and 2, we can conclude that we can create a scope using functions in JavaScript and such functions and variables will not be accessible from outside.

Another example

var x = 10;
function foo () {
    var y = 20;
    return y + x;
}

console.log (x);        // prints 10
var fooX = foo();
console.log (fooX);     // prints 30

What’s the value of fooX? It is 30. The return statement at line no 4 is adding x and y.

Extending the above code snippet with following lines:

x = 20;
fooX = foo();
console.log (fooX);    // prints 40

After changing the value of x to 20, the value of fooX becomes 40. No matter how many times we change the value of x, every time we execute the foo function, we get the result with updated value of x.

This is the simplest form of the closure. A closure is a function (technically which means a scope) which preserves or holds the [outer] scope.

Let’s see another example with the traditional outer and inner functions to explain what a closure is:

function greetings () {
	var greetWith = “Welcome, “;
	return function (name) {
		console.log (greetWith + name);
	}
}

var greet = greetings ();
greet (“Jim”);		// Welcome, Jim
greet (“Pam”);		// Welcome, Pam

If you look closely, this example is similar to what we have seen earlier. The only difference is, we have executed the function greetings before passing different values to greet function. So it is all about keeping a reference of a scope to use the data later.

In applications, closures are created to hide the variables and functions from the other scopes [as discussed]. This is usually done in the module pattern [click here to see an example].

In part II of this post, I’ll talk about another famous and important use of closure.