Module 24 : Closures in JavaScript
🧠 X: Closures in JavaScript
🔍 What is a Closure?
A closure is a function that remembers its lexical scope, even when the function is executed outside that scope.
In simple terms:
A closure gives you access to an outer function’s scope from an inner function.
Closures are created every time a function is created.
📚 Core Concepts
Lexical Environment:
The place where variables and functions are physically written in the code.
Scope Chain:
A chain of variable environments — local, function, and global.
Closure:
When a function retains access to its parent scope, even after the parent function has finished execution.
✅ Syntax and Basic Example
javascript
code
function outerFunction() { let outerVariable = "I'm from outer scope!"; function innerFunction() { console.log(outerVariable); // innerFunction can access outerVariable } return innerFunction; } const myClosure = outerFunction(); // returns innerFunction myClosure(); // Output: I'm from outer scope!
Explanation:
outerFunction defines a variable outerVariable.
innerFunction is defined inside outerFunction and uses outerVariable.
outerFunction returns innerFunction.
Even after outerFunction completes, innerFunction still has access to outerVariable.
This is the essence of closure.
🛠️ Practical Uses of Closures
Data Encapsulation / Private Variables
javascript
code
function counter() { let count = 0; return function () { count++; return count; }; } const increment = counter(); console.log(increment()); // 1 console.log(increment()); // 2
Function Factories
javascript
code
function multiplyBy(x) { return function (y) { return x * y; }; } const double = multiplyBy(2); console.log(double(5)); // 10
Memoization (Caching Results)
javascript
code
function memoizedAdd() { let cache = {}; return function (num) { if (num in cache) { return `From Cache: ${cache[num]}`; } else { cache[num] = num + 10; return `Calculated: ${cache[num]}`; } }; } const add = memoizedAdd(); console.log(add(5)); // Calculated: 15 console.log(add(5)); // From Cache: 15
✏️ Exercises With Explanations
Exercise 1: Create a Greeting Closure
Task:
Write a function createGreeter that takes a name and returns a function that greets using that name.
Solution:
javascript
code
function createGreeter(name) { return function () { console.log(`Hello, ${name}!`); }; } const greetJohn = createGreeter("John"); greetJohn(); // Hello, John!
Explanation:
greetJohn remembers the name passed to createGreeter. This demonstrates closure.
Exercise 2: Encapsulate a Bank Account
Task:
Create a createAccount function that allows deposit and balance checking using closures.
Solution:
javascript
code
function createAccount() { let balance = 0; return { deposit: function (amount) { balance += amount; }, getBalance: function () { return balance; } }; } const account = createAccount(); account.deposit(100); console.log(account.getBalance()); // 100
🔬 Timer Counter Using Closures
Objective:
Use closures to create a timer that counts each second and stops at a defined limit.
Step-by-Step :
Define the timer function
Use closure to maintain state
Use setInterval to update every second
Stop after reaching a limit
javascript
code
function createTimer(limit) { let count = 0; return function () { const interval = setInterval(() => { count++; console.log(`Timer: ${count}s`); if (count === limit) { clearInterval(interval); console.log("Timer finished."); } }, 1000); }; } const startTimer = createTimer(5); startTimer(); // Will count from 1 to 5
Explanation:
The inner function has access to count and limit, even after createTimer returns.
Closure keeps the variables alive inside setInterval.
🔍 Research and Deeper Understanding
1. How Closures Manage Memory
Closures retain variables in memory as long as they are accessible. In modern engines like V8, unused closures are garbage-collected, but leaks may occur if not handled properly.
2. Closures in Frameworks
React Hooks (useState) use closures to retain state between renders.
Redux middleware uses closures for state and dispatch access.
Event handlers use closures to capture element-specific data.
3. Closures and Asynchronous JavaScript
Closures are essential in callbacks and promises. For example:
javascript
code
function fetchData(url) { const timestamp = Date.now(); fetch(url).then(response => { console.log(`Fetched at ${timestamp}`); }); }
Here, timestamp is preserved via closure and used when the promise resolves.
🧠 Summary
Concept
Key Idea
Closure
A function + its lexical environment
Lexical Scope
Scope determined by position in code
Uses
Private variables, memoization, factories
Advanced Usage
Async, React, Event handlers
📝 Homework
Create a closure that tracks a user’s last login time.
Build a shopping cart using closures to add, remove, and total items.
Use a closure to debounce an input field.
No comments:
Post a Comment