Javascript Closures

Vivek
4 min readJun 6, 2019

--

Closures are one of the important concepts of JavaScript and allow developers to write better code. It is somewhat advanced, and often misunderstood feature of the JavaScript language. I recommend you to take a moment to refresh your knowledge regarding Scopes and Execution Context before reading this article.

A closure is the combination of a function and the lexical environment within which that function was declared. — MDN

In simple terms, A closure is an inner function that has access to the outer function’s variables — scope chain. The closure has three scope chains:
- it has access to its own scope.
- it has access to the outer function’s variables.
- it has access to the global variables.

Let’s understand the above definition with the below example:

function outer(){
//outer function scope
let x = 1;
function inner(){
//Inner function scope
let y = 2;
console.log(x + " " + y + " " + z)
}
return inner;
}
// Global scope
let z = 3;
let output = outer();
output();

Here we have two functions:

  • an outer function outer which has a variable x, and returns the inner function
  • an inner function inner which has its variable called y, and accesses an outervariable x and global variable z within its function body.

inner function had preserved the value of x=1 when the outer()function was executed, and continued to preserve (closure) it.

So the inner function has three scope chains:

  • access to its own scope — variable y
  • access to the outer function’s variables — variable x, which it enclosed
  • access to any global variables that may be defined — variable z.

Points to remember:

  • The inner function has access not only to the outer function’s variables, but also to the outer function’s parameters.
function sayHello(name) {
var text = 'Hello ' ; // Local variable
function say() { console.log(text + name); }
return say;
}
var say2 = sayHello('closure');
say2(); // "Hello closure"
  • The local variables are not copied — they are kept by reference. In other words, the value of the variables inside a closure can be modified.
let x = 2;
function outer() {
return function inner(y) {
return x * y
}
}
let myClosure = outer()myClosure(5) // 10x = 4 // value of x will be updated to 4;

myClosure(5) // 20
  • We can use closures to store private data.
function initSalary() {
let salary = 1000;
return {
getSalary: function() {
return salary;
},
setSalary: function(s) {
salary = s;
}
};
}
output = initSalary();console.log(output.getSalary()); // 1output.setSalary(2000);
console.log(output.getSalary()); // 2

Here the function returned an object which has 2 functions. Because they are properties of the object which is bound to the local scope, they are closures. Through getSalary and setSalary, we can manipulate the salary property but we don’t have direct access to it.

Important Interview Questions:

Q1.

for (var i = 0; i < 5; i++) {
setTimeout(function result() {
console.log(i);
}, 1000);
}

Output: 🤔
5
(5 times)

Explanation: The reason for this is because the setTimeout function creates a function (the closure) that has access to its outer scope, which is the loop that contains the index i. After 1 second go by, the function is executed and it prints out the value of i, which at the end of the loop is 5 because it cycles through 0, 1, 2, 3, 4, 5 and the loop finally stops at 5.

Q2

for (var i = 0; i < 5; i++) {
(function(){
var j = i;
setTimeout(function result() {
console.log(j);
}, 1000);
})();
}

Output: 🤔
0
1
2
3
4

Explanation: Here, variable j is local variable, with a copy of the i value at each iteration. After 1 second go by, the function is executed and it prints out the value of j, which at each iteration is 0,1,2,3,4.

Q3

// Outer function 
function outer()
{
var arr = [];
var i;
for (i = 0; i < 4; i++)
{
// storing anonymus function
arr[i] = function () { return i; }
}
// returning the array.
return arr;
}
var get_arr = outer();console.log(get_arr[0]());
console.log(get_arr[1]());
console.log(get_arr[2]());
console.log(get_arr[3]());

Output: 🤔
4(4 times)

Explanation: All four get_arr functions point to the same variable i. By the time any of these functions is invoked, the value of i is 4.
To get 0, 1, 2, 3 as output, one solution is to pass each argument via a self invoking function. Since every function invocation takes place in a unique execution context, it guarantees the uniqueness of the argument variable across successive invocations.

function outer() 
{
var arr = [];
var i;
for (i = 0; i < 4; i++)
{
//IIFE
(function(i){
// storing anonymus function
arr[i] = function () { return i; }

})(i);
}
// returning the array.
return arr;
}
var get_arr = outer();
console.log(get_arr[0]());
console.log(get_arr[1]());
console.log(get_arr[2]());
console.log(get_arr[3]());

This concludes JavaScript Closures from my side. Thanks for reading.

Explore the Series:

Please post any feedback, questions, or requests for topics.If this post was helpful, please click the clap 👏button below a few times to show your support.

--

--