What are Closures in JavaScript
Closure in JavaScript, according to Douglas Crockford, is an inner function that always has access to outer function’s variables and parameters, even after the outer function has returned. The inner nested function has access to the outer function’s parameters but cannot call the outer function’s arguments object.
Let’s illustrate closures with a simple example.
function getCurrentDate() {
var date = new Date();
return date.toISOString();
}
console.log(getCurrentDate());
setTimeout(function () {
console.log(getCurrentDate());
}, 2000);
In the above function, we are printing the current date to the console. The method is invoked twice, after a delay of few seconds, and the date string would be different in each call.
JavaScript Closure
With Closures, the date variable would stick around even after the function has returned and thus we are able to create a container for our variable. Here’s the closure version of the same function.
function dateClosure() {
var date = new Date();
return function () {
return date.toISOString();
};
}
// Instantiate the function
var myClosure = dateClosure();
console.log(myClosure());
setTimeout(function () {
console.log(myClosure());
}, 2000);
Run the function and you’ll get the same value for the date string every single time. To recap, closure is when a function remembers the variables around it even when the function has executed and returned the value.
Here’s another example of a simple closure. By referencing the variable count, the inner function gets a closure over the variable and thus it is going to be preserved even after we return the function. You can call the returned function multiple time and it will increment the count each time.
function counter() {
var count = 0;
return function () {
return count++;
};
}
var myCounter = counter();
console.log(myCounter());
console.log(myCounter());
Here’s another pattern for defining closures.
var counter = function () {
var count = 0;
// Nested function
// Closure created and the variable is preserved in memory
var getCounter = function () {
return count++;
};
// returns a reference to the inner function
return {
val: getCounter,
};
};
var myCounter = new counter();
console.log(myCounter.val());
console.log(myCounter.val());
In the next example, we declare a function that takes a parameter x and returns a function that closes over the variable. The value of x for the add2 function will always be 2.
function sum(x) {
return function (y) {
return x + y;
};
}
var add2 = sum(2);
console.log(add2(5));
console.log(add2(10));
In essence, whenever you nest a function inside another function, a closure is used.
Closures are a way to let a function have persistent (the value is preserved even after the function has executed and returned) and private variables (the variables are local to the function) without polluting the global namespace.
Amit Agarwal
Google Developer Expert, Google Cloud Champion
Amit Agarwal is a Google Developer Expert in Google Workspace and Google Apps Script. He holds an engineering degree in Computer Science (I.I.T.) and is the first professional blogger in India.
Amit has developed several popular Google add-ons including Mail Merge for Gmail and Document Studio. Read more on Lifehacker and YourStory