Closure Fundamentals
Understanding closures and their role in JavaScript scope management
Challenge
Section titled “Challenge”You need to create a counter function that maintains its own private state, incrementing on each call without using classes or global variables. The state should be inaccessible from outside the function.
Explanation
Section titled “Explanation”A closure is created when an inner function has access to variables in its outer (lexical) scope, even after the outer function has returned. This allows for data encapsulation and maintaining private state.
Solution
Section titled “Solution”function createCounter() { let count = 0; // Private variable
return function increment() { count++; return count; };}
const counter = createCounter();console.log(counter()); // 1console.log(counter()); // 2console.log(counter()); // 3// count variable is never accessible directlyKey Concepts
Section titled “Key Concepts”- Lexical Scope: Functions are executed using variable scope that was in effect when they were defined, not when they are called
- Memory Retention: Variables in closures remain in memory as long as the closure exists
- Encapsulation: Closures enable true private variables in JavaScript
Advanced Example: Module Pattern
Section titled “Advanced Example: Module Pattern”const BankAccount = (function() { let balance = 0; // Private variable
return { deposit(amount) { balance += amount; return `Deposited: $${amount}. New balance: $${balance}`; }, withdraw(amount) { if (amount > balance) { return 'Insufficient funds'; } balance -= amount; return `Withdrawn: $${amount}. New balance: $${balance}`; }, getBalance() { return `Current balance: $${balance}`; } };})();
console.log(BankAccount.deposit(100)); // Deposited: $100. New balance: $100console.log(BankAccount.withdraw(30)); // Withdrawn: $30. New balance: $70console.log(BankAccount.getBalance()); // Current balance: $70Interview Question: Memory Considerations
Section titled “Interview Question: Memory Considerations”What happens to memory when creating multiple closures?
function createMultipleCounters(n) { const counters = []; for (let i = 0; i < n; i++) { counters.push((function(num) { return function() { return num++; }; })(i)); } return counters;}Each counter maintains its own closure scope. Using IIFE (Immediately Invoked Function Expression) with parameter ensures each closure captures its own independent value.