Closures in Javascript

Full-Stack Web Developer with over 25 years of professional experience. I have experience in database development using Oracle, MySQL, and PostgreSQL. I have extensive experience with API and SQL development using PHP and associated frameworks. I am skilled with git/github and CI/CD. I have a good understanding of performance optimization from the server and OS level up to the application and database level. I am skilled with Linux setup, configuration, networking and command line scripting. My frontend experience includes: HTML, CSS, Sass, JavaScript, jQuery, React, Bootstrap and Tailwind CSS. I also have experience with Amazon EC2, RDS and S3.
Closures are a fundamental concept in JavaScript, allowing functions to "remember" the environment in which they were created, even after that environment has finished executing. Here are a couple of examples that demonstrate closures in action.
Example 1: Basic Closure
In this example, an inner function retains access to the variables of its outer function, even after the outer function has completed.
function makeCounter() {
let count = 0;
return function() {
count += 1;
return count;
};
}
const counter = makeCounter();
console.log(counter()); // Output: 1
console.log(counter()); // Output: 2
console.log(counter()); // Output: 3
Explanation
makeCounterdefines a variablecountand returns a function that incrementscountby 1 each time it is called.When
makeCounteris called, it returns the inner function, which "closes over" thecountvariable. Even aftermakeCounterhas finished executing, the returned function retains access tocountbecause of the closure.
Example 2: Closure with Parameters
Closures can also capture arguments passed to the outer function, creating a more flexible way to maintain state.
function createMultiplier(multiplier) {
return function(number) {
return number * multiplier;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // Output: 10
console.log(triple(5)); // Output: 15
Explanation
createMultipliertakes amultiplieras an argument and returns a function that multiplies any given number by thatmultiplier.doubleandtripleretain the multiplier values2and3, respectively, because of the closure.When calling
double(5)andtriple(5), the returned functions remember the values passed tocreateMultiplier, allowingmultiplierto persist.
Example 3: Private Variables Using Closures
Closures can be used to create "private" variables in JavaScript, encapsulating data within a function scope.
function BankAccount(initialBalance) {
let balance = initialBalance;
return {
deposit(amount) {
balance += amount;
console.log(`Deposited: $${amount}. New Balance: $${balance}`);
},
withdraw(amount) {
if (amount <= balance) {
balance -= amount;
console.log(`Withdrew: $${amount}. New Balance: $${balance}`);
} else {
console.log("Insufficient funds.");
}
},
getBalance() {
return balance;
}
};
}
const account = BankAccount(100);
account.deposit(50); // Deposited: $50. New Balance: $150
account.withdraw(30); // Withdrew: $30. New Balance: $120
console.log(account.getBalance()); // Output: 120
Explanation
BankAccountdefines a private variablebalancethat is accessible only within thedeposit,withdraw, andgetBalancefunctions.Even though
BankAccounthas finished executing, the returned object retains access tobalancedue to closures.This approach simulates private variables, as
balancecannot be accessed directly outside of theBankAccountfunction.



