Closures are one of the most powerful features in JavaScript, and understanding them can make your code cleaner and more efficient. But what exactly is a closure, and how can you use it in your everyday coding?
A closure is a function that remembers and can access its lexical scope (the variables from the outer function) even after the outer function has finished executing. In simple terms, closures let a function "remember" the environment in which it was created, even if that environment is no longer available.
Let’s dive into a real-world example to see closures in action.👇
Real-World Example: Managing a User's Bank Account đź’°
Imagine you’re building a simple banking system, and you want to track the balance of a user’s account. You need to keep the balance private and allow the user to deposit, withdraw, and check their balance—without directly exposing it.
This is where closures come into play. You can create a function that keeps the balance private and lets the user interact with it through other functions. đź”’
Code Example:
function createBankAccount(initialBalance) {
let balance = initialBalance; // Private variable to store the balance
// Deposit money into the account
function deposit(amount) {
if (amount > 0) {
balance += amount;
console.log(`Deposited $${amount}. New balance: $${balance}`);
} else {
console.log("Deposit amount must be positive.");
}
}
// Withdraw money from the account
function withdraw(amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
console.log(`Withdrew $${amount}. New balance: $${balance}`);
} else {
console.log("Invalid withdrawal amount.");
}
}
// View the current balance
function getBalance() {
console.log(`Current balance: $${balance}`);
}
// Return functions to interact with the balance
return {
deposit,
withdraw,
getBalance,
};
}
// Creating a bank account with an initial balance of $100
const myAccount = createBankAccount(100);
// Interacting with the account using closure functions
myAccount.deposit(50); // Output: "Deposited $50. New balance: $150"
myAccount.withdraw(30); // Output: "Withdrew $30. New balance: $120"
myAccount.getBalance(); // Output: "Current balance: $120"
myAccount.deposit(-20); // Output: "Deposit amount must be positive."
myAccount.withdraw(200); // Output: "Invalid withdrawal amount."
How Does This Work? 🤔
- The
createBankAccount
function initializes thebalance
variable. Thisbalance
is private to thecreateBankAccount
function and cannot be accessed directly from outside. - The inner functions
deposit
,withdraw
, andgetBalance
form closures. These functions remember thebalance
variable and can access and modify it even after thecreateBankAccount
function has finished executing. - The returned object exposes methods (
deposit
,withdraw
,getBalance
) that allow us to interact with the privatebalance
.
Why Is This Useful? 🔑
-
Data Privacy 🛡️: The
balance
is protected from being accessed or modified directly. You can only interact with it through the provided methods, which helps keep the balance secure. -
Persistent State 🔄: The closure allows the inner functions to "remember" the
balance
value, even when they are called later. This means the balance is updated each time you call the functions. - Modularity and Flexibility đź’ˇ: You can easily extend this concept to other parts of the system, such as creating multiple user accounts, each with its own private balance.
Conclusion
Closures are a powerful tool in JavaScript for managing private data and maintaining state over time. In our example, closures allowed us to build a secure banking system where users can deposit, withdraw, and check their balance—without exposing the internal data.
Closures make your code more modular, secure, and flexible. Have you used closures in your projects? Share your experiences or ask any questions in the comments below! 👇
Let's Connect LinkedIn
Top comments (0)