Closure
Advanced JavaScript: Understanding Closures with Real-World Examples
A closure is a function that remembers the variables from its lexical scope even after the outer function has finished executing.
Example 1: Using IIFE (Immediately Invoked Function Expression)
const counter = (function () {
let count = 0;
return function () {
count++;
console.log(count);
};
})();
counter(); // Output: 1
counter(); // Output: 2
counter(); // Output: 3
Example 2: Closure in Loops (Fixing Common Mistakes)
function createTimers() {
for (var i = 1; i <= 3; i++) {
setTimeout(function() {
console.log(`Timer ${i} seconds`);
}, i * 1000);
}
}
createTimers();
Solution Using IIFE
function createFixedTimers() {
for (var i = 1; i <= 3; i++) {
(function (j) {
setTimeout(function () {
console.log(`Timer ${j} seconds`);
}, j * 1000);
})(i);
}
}
createFixedTimers();
Alternative Fix Using let
function createFixedTimersWithLet() {
for (let i = 1; i <= 3; i++) {
setTimeout(function () {
console.log(`Timer ${i} seconds`);
}, i * 1000);
}
}
createFixedTimersWithLet();
Example 3: Function Factories
function multiplyBy(factor) {
return function(number) {
return number * factor;
};
}
const double = multiplyBy(2);
const triple = multiplyBy(3);
console.log(double(5)); // Output: 10
console.log(triple(5)); // Output: 15
Example 4: Memoization (Performance Optimization)
function memoizedFactorial() {
let cache = {};
return function factorial(n) {
if (n in cache) {
console.log("Fetching from cache:", n);
return cache[n];
}
if (n === 0 || n === 1) return 1;
console.log("Calculating result:", n);
cache[n] = n * factorial(n - 1);
return cache[n];
};
}
const fact = memoizedFactorial();
console.log(fact(5));
console.log(fact(5));
Summary
- Closures allow functions to remember variables from their outer scope.
- Used for private variables, function factories, loops, and performance optimization.
- Common patterns:
- Encapsulation
- Fixing loops with
varandlet - Function factories
- Memoization
Comments
Post a Comment