Js Hoisting Closures Real World
Js Hoisting Closures Real World
Real-World Scenarios
Real-World Use Cases of Closures
1. Private Variables and Encapsulation
// Real-world: Creating a secure bank account module
function createBankAccount(initialBalance) {
let balance = initialBalance; // Private variable
let transactions = []; // Private transaction log
return {
deposit(amount) {
if (amount > 0) {
balance += amount;
transactions.push({ type: 'deposit', amount, timestamp: new Date() });
return balance;
}
throw new Error('Deposit amount must be positive');
},
withdraw(amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
transactions.push({ type: 'withdrawal', amount, timestamp: new Date() });
return balance;
}
throw new Error('Insufficient funds or invalid amount');
},
getBalance() {
return balance;
},
getTransactionHistory() {
// Returns a copy to prevent direct manipulation
return [...transactions];
}
};
}
function memoize(fn) {
const cache = new Map();
return function(arg) {
if (cache.has(arg)) {
console.log(`Returning cached result for ${arg}`);
return cache.get(arg);
}
const result = fn(arg);
cache.set(arg, result);
return result;
};
}
return function() {
count++;
console.log(`Button ${buttonId} clicked ${count} times`);
// Each button maintains its own independent count
};
}
document.getElementById('btn1').addEventListener('click', button1Handler);
document.getElementById('btn2').addEventListener('click', button2Handler);
// Problematic Version
for (var i = 0; i < 3; i++) {
result.push(function() {
console.log(i); // What will this print?
});
}
return result;
}
// Correct Solutions:
// Solution 1: Using let (block-scoped)
function createFunctionsFixed1() {
let result = [];
return result;
}
function privateMethod() {
console.log('Internal count:', count);
}
// Public interface
return {
increment() {
count++;
privateMethod();
return count;
},
decrement() {
count--;
privateMethod();
return count;
},
getCount() {
return count;
}
};
})();
console.log(counterModule.increment()); // 1
console.log(counterModule.increment()); // 2
console.log(counterModule.getCount()); // 2
// count is not directly accessible
let x = 10;
const y = 20;
console.log(x); // 10
console.log(y); // 20
}
Interview Strategy
Closure Interview Preparation
1. Understand closure mechanism
2. Practice creating closures
3. Recognize common patterns
4. Be able to explain privacy and state preservation
Hoisting Interview Preparation
1. Know the difference between var, let, const
2. Understand function hoisting rules
3. Recognize potential pitfalls
4. Demonstrate ability to write clean, predictable code
Key Takeaways
Closures are powerful for data privacy and state management
Hoisting can lead to unexpected behaviors
Always prefer let and const over var
Understand scope and execution context
Practice Challenges
1. Implement a complete memoization function
2. Create a counter module with advanced features
3. Write a function that demonstrates closure in an event-driven scenario
Would you like me to elaborate on any of these examples or provide more in-depth explanations of any specific scenario?