Tricky Closure in JavaScript

Most confusing topic in Javascript is Closure. So let’s try to understand what it is.

What is Closure?

A closure is an inner function that has access to the outer enclosing function’s variables — scope chain. 
The closure has three scope chains: 
- it has access to its own scope (variables defined between its curly brackets).
- it has access to the outer function’s variables.
- it has access to the global variables.

Closure means that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned.

Example —

function getSum() {
var num1= 2;
return function calculate() {
var num2= 3;
console.log(num1+num2);
}
}
var sum = getSum()
console.log(sum) // calculate(){var num2 = 2;
//console.log(num1+num2) }
sum() // 5

getSum() is the outer function that has a variable num1 and return the calculate() inner function.

  • calculate() function has its variable num2, and access getSum variable num1.

Function Execution steps-

  • first getSum() function get invoked
  • then num2 get created and its scope is limited to the getSum() function.
  • after that getSum() function return the calculate() function and we assign it into variable sum as show below
var sum = calculate() {
var num2= 3;
console.log(num1+num2);
}
As we know the inner function preserves the scope chain of the enclosing function at the time the enclosing function was executed, and thus can access the enclosing function’s variables.
  • In our example calculate() function preserve the value of the num1 variable that was defined in getSum() function.
  • In last when we execute the sum() function it return the sum of num1 + num2 = 5

Tricky example with Closure

  • Look at the below example and let’s try to fix the issue.
  • On execution of createArrFunction() function, a variable arr get created and a for loop run that pushes an anonymous function to variable arr five times and returns the variable arr
  • If you print the getArrFunction() function you will get an array of five functions as shown below
[ƒ (){ console.log(i)},ƒ (){ console.log(i)},ƒ (){ console.log(i)},ƒ (){ console.log(i)},ƒ (){ console.log(i)}]
  • Now, when we execute the first function within the array it return a value of 5 instead of 0.
getArrFunction[0]() // 5

Reason for this strange behavior is that the time we executed the Outer function(createArrFunction) the last value of variable i was 5 which get persevered by the inner function.so it’s returning 5 instead of 0.

Solutions to this issue are —

a) Solution 1 — use let instead of var in for loop we can solve this issue.

let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.

b) solution 2 — Use ‘Immediately Invoked Function Expression(also known as an IIFE)

  • Immediately Invoked Function Expression is a good way at protecting the scope of your function and the variables within it
An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.
(function () {
statements
})();
  • If you see above example we have used the IIFE in line no 5 which causes the inner function to execute immediately and preserve the current value of var i.


Get your own blog published on C2E Blog

Do you want to write for CodeToExpress? We would love to have you as a technical writer. Send us an email with a link to your draft at codetoexpress@gmail.com