Table of contents
Introduction
Closures are created when the function is defined, allowing the nested child function to access the parent's variables even when the parent function has finished its execution. Now let's learn Closures with examples.
Examples
From the below example, we can learn how we can emulate private variables and functions with the help of closures.
// global scope let x = 1; const parentFunction = () => { let myValue = 2; // accessing the global variable x inside the parentFunction console.log(x); console.log(myValue); const childFunction = () => { // nested child function can access the variables of parentFunction // and global variables as well console.log((x += 5)); console.log((myValue += 1)); }; return childFunction; }; const parentResult = parentFunction(); // we are able to access the parent Variables even though parent function has finished executing. parentResult(); parentResult(); parentResult(); // we will not get 1 as we are able to access the global variable and we are changing it's value within childFunction console.log(x);
Example of closure with IIFE.
const withdrawMoney = ((money) => { let amount = money; console.log(`Initial amount: ${amount}`); return () => { amount -= 1000; if (amount > 0) { console.log(`Money withdrawn 1000, money left ${amount}`); } if (amount <= 0) { console.log("can't withdraw money"); } }; })(3000); // everytime we are running withdrawMoney function amount is getting // deducted by 1000 withdrawMoney(); withdrawMoney(); withdrawMoney();
A real-life example of closures: let's say we want to change the background colour of the web page based on the button clicked.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <button id="orange">orange</button> <button id="red">red</button> <button id="green">green</button> <script> function clickHandler(color) { return () => { document.body.style.backgroundColor = color; }; } document.getElementById("orange").onclick = clickHandler("orange"); document.getElementById("green").onclick = clickHandler("green"); document.getElementById("red").onclick = clickHandler("red"); </script> </body> </html>
Disadvantages
Memory Usage: Closures can lead to more memory usage as the entire scope chain will exist in the memory until all the closure references are removed. This means that the variables which would have been removed by the garbage collector will exist in the memory as long as the closure exists.
function outerFunction(value) {
let arr = new Array(100000).fill(value);
return () => {
console.log(value);
}
}
const innerfunction = outerFunction(10)
// array created above will stay in the memory as long as the closure exists
Conclusion
JavaScript closure is a incredibly useful feature which allows nested function to access the parent variable even, when the parent function has finished it's execution. It allows to emulate private variables, maintaining state in an application, and facilitating event handling in a web browser. However, closures have their disadvantages as well, this can lead to increased memory usage as entire scope chain will exist in the memory until all the closure references are removed. Understanding closures and their advantages and disadvantages is essential for effective JavaScript programming.