Quick Closure: How to Write Closures for Simple Javascript Functions
Understanding and implementing JavaScript closures with a practical timestamp conversion example.
Quick Closure: How to Write Closures for Simple Javascript Functions
Note: This is a restored article from the original A thousand nodes blog (circa 2012).
This is a quick example of how to use closures in JavaScript. For this demonstration, I'll create a small function that helps convert timestamps into formatted dates.
What is a Closure?
A closure is a function that remembers the environment in which it was created, including any local variables that were in scope at that time.
The Problem
Let's say we need to convert Unix timestamps to formatted dates throughout our application. Without closures, we might write the same conversion code multiple times or create a global helper function.
The Solution: Using Closures
Here's how to create a reusable timestamp converter using closures:
var dateFromTimestamp = (function() {
// Private variables and functions inside the closure
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
// This function formats a date object according to our needs
function formatDate(dateObj) {
var month = months[dateObj.getMonth()];
var day = dateObj.getDate();
var year = dateObj.getFullYear();
var hours = dateObj.getHours();
var minutes = dateObj.getMinutes();
// Add leading zeros to minutes if needed
if (minutes < 10) {
minutes = '0' + minutes;
}
return day + ' ' + month + ' ' + year + ', ' + hours + ':' + minutes;
}
// Return the actual function that will be used
return function(timestamp) {
// Create a date object from the timestamp
var date = new Date(timestamp * 1000); // Convert to milliseconds
return formatDate(date);
};
})();
How to Use It
// Example usage
var timestamp = 1351515600; // October 29, 2012
console.log(dateFromTimestamp(timestamp)); // Outputs: "29 Oct 2012, 12:00"
// Use it again with a different timestamp
var anotherTimestamp = 1356998400; // January 1, 2013
console.log(dateFromTimestamp(anotherTimestamp)); // Outputs: "1 Jan 2013, 0:00"
Why Use Closures?
- Encapsulation: The months array and formatDate function are private, not polluting the global namespace.
- Reusability: The function can be reused without recreating these resources.
- Performance: The months array is created only once, not each time the function is called.
Closure Syntax Breakdown
Let's break down what's happening:
- We define an anonymous function:
(function() { ... })
- We immediately invoke this function:
(function() { ... })()
- Inside this function, we define private variables and helper functions
- We return another function that uses these private variables and functions
- The returned function is assigned to
dateFromTimestamp
Advanced Usage
You can extend this pattern to create more flexible date formatters:
var createDateFormatter = function(format) {
// Private variables and functions
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
// Return a custom formatter function based on the format parameter
return function(timestamp) {
var date = new Date(timestamp * 1000);
if (format === 'short') {
return date.getDate() + ' ' + months[date.getMonth()];
} else if (format === 'long') {
return date.getDate() + ' ' + months[date.getMonth()] + ' ' +
date.getFullYear() + ', ' + date.getHours() + ':' +
(date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
} else {
// Default format
return date.toLocaleDateString();
}
};
};
// Create different formatters
var shortDateFormatter = createDateFormatter('short');
var longDateFormatter = createDateFormatter('long');
console.log(shortDateFormatter(1351515600)); // "29 Oct"
console.log(longDateFormatter(1351515600)); // "29 Oct 2012, 12:00"
Closures are one of JavaScript's most powerful features. They might seem complex at first, but once you understand them, they become an essential tool in your JavaScript programming toolkit.