Closures are a fundamental concept in JavaScript, yet many developers find them confusing or difficult to understand. At their core, closures are simply functions that have access to variables from their outer (enclosing) function. This can be incredibly powerful, allowing you to create private variables, encapsulate functionality, and avoid naming collisions.
Here’s an example of a closure in action:
function counter() {
let count = 0;
return function incrementCounter() {
count++;
console.log(count);
}
}
const myCounter = counter();
myCounter(); // logs 1
myCounter(); // logs 2
myCounter(); // logs 3
// ...and so on
In this example, counter
is a factory function that returns another function, incrementCounter
. The incrementCounter
function has access to the variable count
, which is defined in its enclosing scope. Each time we call myCounter()
, it increments the value of count
and logs it to the console. Because count
is declared with the let
keyword, it is not accessible outside of the counter
function, ensuring that our counter remains private and cannot be accidentally…