Open In App

How to use a closure to create a private counter in JavaScript ?

Last Updated : 03 Nov, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

A closure is a 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.

Example: Here the inner forms closure with outer. The str variable can be called a private member whose value we can access, but not modify directly.

Javascript




<script>
    function outer() {
        let str = "GeeksforGeeks";
        function inner() {
            console.log(str);
        }
        return inner;
    }
    const fun = outer();
    fun();
</script>


Output:

GeeksforGeeks

The concept of a private counter means that publicly/globally we could not modify the counter variable directly. The below step-by-step guide will teach you how to implement a private counter with closure and understand it.

Step 1: Create counter.js and index.html files. You can give any allowed names to the files.

Step 2: First begin with the index.html file and create a front-end to see the counter. We would create a <div> to show the value of the counter and two buttons, one for incrementing and the other for decrementing the counter.

index.html




<!DOCTYPE html>
<html lang="en">
  
<head>
    <!-- counter.js becomes available
    at execution time-->
    <script src="counter.js"></script>
</head>
  
<body>
    <h1 style="color: blue;">
        Private Counter using Closure
    </h1>
  
    <!-- This div displays the value of
    private counter-->
    <div id="counter_div" style=
        "margin-left: 5%; color: red;">
  
        <!-- Default value of counter is zero-->
        <h2>0</h2>
    </div>
  
    <!-- Buttons for incrementing and 
    decrementing the value of private counter-->
    <button onclick="counterHandler(this)" 
        value="1">
        Increment
    </button>
      
    <button onclick="counterHandler(this)" 
        value="0">
        Decrement
    </button>
</body>
  
</html>


Here we are handling clicks on buttons using the counterHandler function which is in the JavaScript file. The value of the buttons helps us to distinguish which button was clicked. And have an id of the div so that we could use it to update it from JavaScript code.

Step 3: Let’s now work with the counter.js file and implement behind-the-scenes functions.

counter.js




// Global function which would form
// closure with modify function
function counter() {
  
  // Private counter variable
  let count = 0;
  
  // To increment the value of counter
  function increment() {
    count++;
  }
  
  // To decrement the value of counter
  function decrement() {
    count--;
  }
  
  // Modify function forms closure
  // here which is used outside
  function modify(val) {
  
    // To check increment or decrement
    // button has been clicked
    if (val === "1") increment();
    else if (val === "0") decrement();
  
    // Return the counter
    return count;
  }
  
  // Returning to make it available
  // outside counter function
  return modify;
}
  
// Storing the closure modify
const closure = counter();
  
// This function handles the button
// click, objButton to get value
function counterHandler(objButton) {
  
  // Storing the value return by modify
  let count = closure(objButton.value);
  
  // Getting div by it's id
  // and modifying its inner html
  document.getElementById("counter_div")
    .innerHTML = "<h2>" + count + "</h2>";
}


When the buttons get clicked counterHandler is called, we get the value of the button from objButton Object. If the value is one (1) then to be incremented else to be decremented the value of the counter which is count variable.

In the counter function, we have a counter variable count, increment function to increment, and decrement function to decrement the value by one. The modify function is returned as closure to the global when the counter function is called and we store its instance in closure constant.

Finally, we modify the div content to the value of the counter returned by closure using its innerHTML property.

Step 3: Copy the full path of the HTML index.html file and paste it into any browser. After loading the HTML file in the browser, you would see something similar to it. Now play with the increment and decrement buttons and observe the value of counter changing.

Now let’s see what happens in the backend using Developers Tool when the button is clicked. In the below image we had made the counter value equals -1. To see how the scope is defined and related to it.

Scope in Developers Tool

Counter value on the frontend

This is how you could implement a private counter variable using closures in JavaScript. Closures provide a way to achieve the functionality of data encapsulation in JavaScript.

References: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads