Closure in JavaScript: Explanation with Example

Closure in JavaScript: Explanation with Example

22 Aug 2024
Intermediate
400 Views
15 min read
Learn with an interactive course and practical hands-on labs

JavaScript For Beginners Free Course

Closures in JavaScript

Closures in JavaScript are functions that have access to variables from their containing scope even after the parent function has finished executing. Closures are essential to keep the data safe, create more accessible code, and implement callback functions with a continual state.

In this JavaScript tutorial, we will understand closures in JavaScript and how to create them, including their advantages and disadvantages and their uses.

Read More: Functions in JavaScript: User-Defined and Standard Library Functions

Note: Before You learn about Closure in JavaScript, You should understand two concepts:
  • Nested Function
  • Return Function

Nested Function

The Nested function is a function declared within another function. This creates a hierarchical relationship between the functions, where the inner function has access to the variables and parameters of the outer function.

Example

// nested function example
// Declaration of outer function
function MyFunc(name) {
    // Declaration of inner function
    function ShowName() {
        console.log('Hi' + ' ' + name);
    }
    // calling inner function
    ShowName();
}
// calling outer function
MyFunc('Aman');      

Output

Hi Aman

Explanation

In this above example, we have declared a nested function ShowName() that is inside the outer function MyFunc() with parameter name:

  • First, we call the inner function ShowName(), which executes the function definition of the inner function.
  • Then, we call the outer function MyFunc() with arguments Aman, which executes the outer function definition, which is the inner function, and prints the result in the console.

Return Function

In JavaScript, the function returns a specific value using the return statement. When a function executes and reaches to the return statement, it stops the execution and sends the return value to the caller. Without a "return" statement, the function returns 'undefined.'

Example

//Declare function to find square of a number
function findSqr(num) {
   // return square
    return num * num; 
}
// Now calling the function and storing the result
let square = findSqr(4);
console.log(`Square: ${square}`);        

Output

Square: 16 

Explanation

In this example, we declare a function findSqr(num) with the parameter and call the function by passing the arguments 4.
  • After calling, the return statement is used to calculate the square of the root.
  • Then, we save it in a square variable and print the result.

What are Closures in JavaScript?

Closure in JavaScript is a function that has an approach to variables from its outer (enclosing) function, even after the outer function has returned. In simpler terms, it's a function bundled together with its lexical environment. When you create a closure, you get access to an outer function’s scope from an inner function. Closures are naturally created every time a function is defined in JavaScript.

Critical Components of Clousere in JavaScript

  • Inner Function: The function defined within the outer function.
  • Outer Function: The function that encloses the inner function.
  • Lexical Environment: Where the function was made, including variables and their values.

How to create Closure in JavaScript?

A Closure is made when a function is defined. The inner function has an approach to the variables in the outer function's scope, even after the outer function has returned. Let's understand with an example how to create closure:

Example

function outerFunction(outerVariable) {
  return function innerFunction() {
    console.log(outerVariable);
  };
}
const myClosure = outerFunction('Hello from outer function');
myClosure();        

Output

Hello from outer function

Here is the breakdown:

  • Outer function: Defines an outerVariable and returns an inner function.
  • Inner function: Accesses the outerVariable from its enclosing scope.
  • Closure creation: When outerFunction returns, it returns a reference to the innerFunction. Now, this inner function has a closure over the outerVariable
  • Calling the closure: Assigning the returned function to myClosure and calling it later demonstrates that the closure retains access to the outerVariable even after the outer function has finished executing.

Example

function createCounter() {
  let count = 0;
    return {
    increment: () => {
      count++;
      return count;
    },
    decrement: () => {
      count--;
      return count;
    }
  }; 
}
const counter = createCounter();
console.log(counter.increment());
console.log(counter.increment());
console.log(counter.decrement()); 

Output

1
2
1

Explanation

In this given example,
  • We define a function createCounter(), which returns an object. Within createCounter(), we declare a variable count which is private to the function.
  • The returned object contains two functions: increment and decrement. Both functions have access to count due to closure.
  • When we call createCounter, it returns an object with the two functions. We can then use these functions to modify the private count variable without direct access to it.

Advantages of Clousere in JavaScript

Closures offer several benefits that make them a powerful tool in JavaScript development:
  • Data Privacy
  • Creating stateful functions
  • Higher-Order Functions
  • Event Handling

Disadvantage of Closure in JavaScript

While closures are a powerful tool, they also come with potential drawbacks:
  • Performance Impact
  • Memory Consumption

Practical Use of Closure in JavaScript

Closures are a powerful tool in JavaScript, offering numerous practical applications. Here are some common uses;

1. Creating Private Variables and Methods: JavaScript doesn't naturally support variables. Closure can follow this behavior.

Example

function counter() {
    let count = 0;
    return {
      increment: () => count++,
      decrement: () => count--,
      getCount: () => count
    };
  }
  const counter1 = counter();
  const counter2 = counter();
  console.log(counter1.getCount());
  counter1.increment();
  console.log(counter1.getCount()); 
  console.log(counter2.getCount());      

Output

0
1
0

Explanation

In this above example,
  • counter1 and counter2 are separate instances of the counter function.
  • Each instance has its private count variable.
  • Therefore, modifying counter1 does not affect counter2.

2. Creating curried function: It is used to create new functions by partially applying arguments to existing functions and useful for creating specialized functions based on initial parameters.

Example

function multiply(x) {
  return (y) => x * y;
}
const double = multiply(2);
const triple = multiply(3);
console.log(double(5)); 
console.log(triple(5));      

Output

10
15

Explanation

In the above example, multiply is a curried function. It takes one argument, x, and returns another function that takes y and returns its product.
  • We use closures to create functions (double and triple) that remember the multiplier (x) from the multiply function and apply it to the input (y) when called.
  • This allows double(5) to return 10 and triple(5) to return 15 by preserving the context of x.
Summary

The closure in JavaScript is the most important programming construct in the journey of learning JavaScript. We saw the Clousere in complete detail. You should practice the concepts you understand from this tutorial. For a better understanding, consider our JavaScript Programming Course.

ScholarHat provides different types of training and certification courses to help you develop your end-to-end product.

FAQs

In the JavaScript tutorial,
  • Hoisting is a JavaScript behavior where variable and function declarations are moved to the top of their scope before code execution. 
  • Closure is a function that has access to variables from its outer (enclosing) function, even after the outer function has returned.   

In JavaScript, a promise is an object representing the eventual completion (or failure) of an asynchronous operation and its resulting value.

If you need to minimize or avoid closure, you can consider the following approaches:
  • Use global variable
  • Use object properties
  • Use classes
  • Use arrow functions wisely

Take our Javascript skill challenge to evaluate yourself!

In less than 5 minutes, with our skill challenge, you can identify your knowledge gaps and strengths in a given skill.

GET FREE CHALLENGE

Share Article
About Author
Shailendra Chauhan (Microsoft MVP, Founder & CEO at Scholarhat by DotNetTricks)

Shailendra Chauhan is the Founder and CEO at ScholarHat by DotNetTricks which is a brand when it comes to e-Learning. He provides training and consultation over an array of technologies like Cloud, .NET, Angular, React, Node, Microservices, Containers and Mobile Apps development. He has been awarded Microsoft MVP 9th time in a row (2016-2024). He has changed many lives with his writings and unique training programs. He has a number of most sought-after books to his name which has helped job aspirants in cracking tough interviews with ease.
Accept cookies & close this