Closures in JavaScript

Closures in JavaScript

A short read on the concept and applications of Closures in JavaScript

Hello folks! In this blog I would like to talk on one of the basic phenomenon in Javascript, Closures. We are often asked about closures and its role and functionalities in our interviews, so let us talk in detail about the working principle and the phenomenon altogether now.

CLOSURES

According to MDN,

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.

Closures are created whenever a function is created at the time of function creation.

Consider this code now,

function myFunction(){
var user={
name:"John",
city: "NewYork"
}
function printUser(){
console.log(user.name+" "+user.city);
}
printUser();
}


res();

myFunction creates local variables user and function printUser(). printUser is the inner function defined inside myFunction() and is available only inside parent outer function. The inner function does not have any local variable of its own although, inner functions have access to the local variables of the outer function and hence printUser has access to user variable and prints the expected result.

This is called "lexical scoping" which defines how code is parsed and variable are resolved in case of nested functions. The term "lexical", means that the variables are resolved on the basis of their location in the code to determine the availability. In this scenario, nested functions have access to the local variables of the outer function.

Now post knowing about lexical scope, let us learn about how it is useful in terms of closures.

For instance,

function myFunc(){
var user={
name:"John",
city: "NewYork"
}
function printUser(){
console.log(user.name+" "+user.city);
}
return printUser;
}

var res=myFunc();
res();

In this scenario, myFunc() returns inner function printUser() on call. In other programming languages, when inner function is extracted out of its parent scope, it does not have access to the local variables of the parent function as in case of lexical scoping. But in Javascript, functions tend to remember the variables present in the parent lexical scope and not throw an error. This is "Closure".

Closures are nothing but a combination of the function involved and its lexical scope within which the former inner function was declared. In the above code example, a closure is formed inside parent function myFunc(), which includes inner function printUser() (which is returned from the parent function) along with the user variable present in the inner function's lexical scope. Hence, when res() is invoked, variable user is available for usage.

Practical use of Closures

Closures are quite useful in case of web development scenarios. For example, we need to change font-color of the page . Refer to the code below,

//JS
function colorChanger(color) {
  return function() {
    document.body.style.color =  color;
  };
}

var red = colorChanger("red");
var blue = colorChanger("blue");
var green = colorChanger("green");




document.getElementById('red').onclick = red;
document.getElementById('blue').onclick = blue;
document.getElementById('green').onclick = green;

<button id="#red">Red</button>
<button id="#blue">Blue</button>
<button id="#green">Green</button>

Closure with the argument color inside function changeColor() makes available "color" to the returned anonymous function.

Accessing Private data from functions using Closures

var count = (function() {
  var privateCount = 0;
  function change(val) {
    privateCount += val;
  }

  return {
    increment: function() {
      change(1);
    },

    decrement: function() {
      change(-1);
    },

    value: function() {
      return privateCount;
    }
  };
})();

console.log(counter.value());  // 0.

count.increment();
count.increment();
console.log(count.value());  // 2.

count.decrement();
console.log(count.value());  // 1.

The anonymous function contains private variable privateCount and change() function which are present in the lexical scope of public functions count.increment, count.decrement, count.value making a closure inside function parent scope of count().

Independent Nature of extracted counters

var count = (function() {
  var privateCount = 0;
  function change(val) {
    privateCount += val;
  }

  return {
    increment: function() {
      change(1);
    },

    decrement: function() {
      change(-1);
    },

    value: function() {
      return privateCount;
    }
  };
})();
var count1=count();
var count 2=count()
console.log(count1.value(),coun2.value() );  // 0 0

count1.increment();
count1.increment();
count2.increment();
console.log(count1.value());  // 2


console.log(count2.value());  // 1

The extracted counters count1 & count2 are separate copies and work independently with same reference to the closure containing private variables.

So, I hope you guys enjoyed reading and going through the what, where and why related to closures in Javascript in this blog. Closures communicate once again that functions are "first class citizens" of Javascript and are capable of remembering their lexical scope and variables which are not even declared in their own local scope.

Thankyou for reading, Ciao!

ย