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 = "neveropen" ; function inner() { console.log(str); } return inner; } const fun = outer(); fun(); </script> |
Output:
neveropen
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.
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