Summary: In this tutorial, you will learn how does closures works in JavaScript with the help of the examples.
Closure in JavaScript
In JavaScript, a closure is a function that retains access to the variables of the context in which it was created, even after the function has been executed and the context in which it was created no longer exists.
The function defined within the closure has access to the variables in the outer function’s scope, even after the outer function has returned.
This is possible because the inner function maintains a reference to the outer function’s variables.
Here’s an example:
function outerFunction(x) {
let outerVariable = x;
return function innerFunction() {
console.log(outerVariable);
}
}
let closure = outerFunction(10);
closure(); // Output: 10
In this example, the innerFunction
has access to the outerVariable
even after the outerFunction
has returned. When the closure
is called, it logs the value of outerVariable
, which is 10
.
Closures are often used to create private variables and methods, which can only be accessed by the inner function.
They are also used to create function factories, which are functions that return new functions with a different context.
Here’s another example of a closure in JavaScript:
function createCounter() {
let count = 0;
return {
increment: function() {
count++;
},
getCount: function() {
return count;
}
};
}
let counter = createCounter();
console.log(counter.getCount()); // Output: 0
counter.increment();
console.log(counter.getCount()); // Output: 1
counter.increment();
console.log(counter.getCount()); // Output: 2
In this example, the createCounter
function returns an object with two methods: increment
and getCount
.
The increment
method increments a count
variable, which is defined in the outer function and is retained by the inner function even after the createCounter
function has returned. The getCount
method returns the current value of count
.
Because the count
variable is retained by the inner function, it is effectively a private variable that can only be accessed by the increment
and getCount
methods.
This is an example of how closures can be used to create private variables and methods in JavaScript.
JavaScript Closures in Loop
One common pitfall that developers encounter when using closures in a loop is that the value of the loop variable is captured by the closure, but the value of the loop variable is not updated as the loop executes.
This can be confusing because the value of the loop variable is different from the value that is captured by the closure.
Here is an example of how this can happen:
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
This code will output the number 3 three times, rather than the numbers 0, 1, and 2 as you might expect. This is because the value of the i
variable is captured by the closure, but the value of the i
variable is not updated as the loop executes.
One way to work around this issue is to use an IIFE (Immediately Invoked Function Expression) to create a new scope for each iteration of the loop:
for (var i = 0; i < 3; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
This will output the numbers 0, 1, and 2 as expected.
Alternatively, you can use the let
keyword to declare the loop variable, which will create a new binding for each iteration of the loop:
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
This will also output the numbers 0, 1, and 2 as expected.