Closure in js
Table of contents
No headings in the article.
Closure in JavaScript refers to the ability of a function to access and remember the values of variables declared outside of its own scope, even after the outer function has returned.
When a function is defined within another function, the inner function has access to all the variables and parameters of the outer function, even after the outer function has finished executing. This means that the inner function can continue to access and modify those variables even when it is invoked later on, outside the outer function.
This concept is particularly useful for creating private variables and functions within an object, where the variables and functions are inaccessible from outside the object but can still be used by other methods within the object.
In simpler terms, closure allows a function to remember and use variables and functions from its parent function even after the parent function has finished running.
Here are a couple of examples of closure.
Example 1: Creating a private variable using closure
function counter() {
let count = 0;
return function() {
count++;
console.log(count);
}
}
const increment = counter();
increment(); // 1
increment(); // 2
increment(); // 3
In this example, the counter
function returns another function that increments a private variable count
each time it is called. The count
variable is not accessible from outside the counter
function, but the returned function can still access and modify it thanks to closure.
Example 2: Creating a function factory using closure
function createMultiplier(multiplier) {
return function(num) {
return num * multiplier;
}
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
In this example, the createMultiplier
function returns another function that multiplies its argument by the multiplier
parameter passed to createMultiplier
. By returning a function, createMultiplier
can be used to create different multiplier functions with different values of multiplier
. Each of these functions has access to the multiplier
value even after createMultiplier
has returned, thanks to closure.
Example 3: Creating an event listener using closure
function addEvent(element, eventType, handler) {
element.addEventListener(eventType, function(event) {
handler(event);
});
}
const button = document.querySelector('button');
addEvent(button, 'click', function(event) {
console.log('Button clicked!');
});
In this example, the addEvent
function takes an element, an event type, and a handler function and adds an event listener to the element that calls the handler function when the event occurs. The handler function has access to the handler
parameter even after addEvent
has returned, thanks to closure. This allows the handler function to perform some action when the event occurs, such as logging a message to the console in this case.
Here's a practical React example that uses closure:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
function decrement() {
setCount(count - 1);
}
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default Counter;
In this example, we have a Counter
component that displays a count and two buttons to increment and decrement the count. The useState
hook is used to create a state variable count
and a function setCount
to update it.
The increment
and decrement
functions are defined inside the Counter
component and use closure to access the count
and setCount
variables. When the user clicks the increment or decrement button, the corresponding function is called and updates the count
state variable.
The use of closure here is important because it allows the increment
and decrement
functions to have access to the count
state variable even after the Counter
component has rendered and returned. This ensures that the count is always updated correctly when the user clicks the buttons.