Understanding JavaScript Closures Through a Timer Example


Closures are a fundamental concept in JavaScript programming that often seem abstract at first but become incredibly clear with practical examples. Today, we’ll explore JavaScript closures using a simple timer system and demonstrate how they allow us to create private variables and encapsulate functionality.
What Are Closures in JavaScript?
Closures in JavaScript are created when a function “remembers” the scope in which it was defined, even after that scope has exited. This means a function can access variables from its parent scope, even if the parent function has already finished executing.
Let’s dive into an example to understand closures better.
Building a JavaScript Timer System
Imagine we want to create a timer that keeps track of elapsed time. The timer should have the following functionalities:
Start the timer to begin tracking time.
Pause the timer to stop tracking temporarily.
Reset the timer to set elapsed time back to zero.
Check the elapsed time at any point.
Here’s how we can implement it in JavaScript:
function createTimer() {
// Private variable to store elapsed time
let elapsedTime = 0;
let intervalId = null;
// Function to start the timer
function start() {
if (!intervalId) {
intervalId = setInterval(() => {
elapsedTime += 1;
console.log(`Elapsed Time: ${elapsedTime} seconds`);
}, 1000);
} else {
console.log("Timer is already running.");
}
}
// Function to pause the timer
function pause() {
if (intervalId) {
clearInterval(intervalId);
intervalId = null;
console.log("Timer paused.");
} else {
console.log("Timer is not running.");
}
}
// Function to reset the timer
function reset() {
elapsedTime = 0;
if (intervalId) {
clearInterval(intervalId);
intervalId = null;
}
console.log("Timer reset to 0 seconds.");
}
// Function to check the elapsed time
function checkTime() {
console.log(`Elapsed Time: ${elapsedTime} seconds`);
}
// Expose the functions as an object
return {
start,
pause,
reset,
checkTime,
};
}
How Closures Work in the Timer System
Private Variables: The
elapsedTime
andintervalId
variables are private to thecreateTimer
function. They are not directly accessible from outside the timer, ensuring better encapsulation.Public Methods: The methods
start
,pause
,reset
, andcheckTime
are returned as part of an object. These methods can access and manipulate the private variables thanks to closures.
Example Usage of the Timer System
Let’s test the timer system:
const timer = createTimer();
timer.start(); // Starts the timer and logs elapsed time every second
setTimeout(() => {
timer.pause(); // Pauses the timer after 5 seconds
timer.checkTime(); // Logs the elapsed time
timer.reset(); // Resets the timer
}, 5000);
Output:
Elapsed Time: 1 seconds
Elapsed Time: 2 seconds
Elapsed Time: 3 seconds
Elapsed Time: 4 seconds
Elapsed Time: 5 seconds
Timer paused.
Elapsed Time: 5 seconds
Timer reset to 0 seconds.
Why This JavaScript Example Is Powerful
Encapsulation: The
elapsedTime
andintervalId
variables are private to each timer instance, ensuring data is protected from accidental external manipulation.Independent Instances: Each call to
createTimer
creates a new instance with its own private state. Changes to one timer do not affect another.Reusability: The
createTimer
function is a reusable blueprint. You can create multiple timers, each with its own independent functionality.
Exploring JavaScript Closures Further
This timer example demonstrates the practical use of closures in JavaScript, but closures can do so much more. They’re used in:
Callback functions in asynchronous JavaScript programming.
Function factories that generate customized functions.
Module patterns for structuring JavaScript code.
Final Thoughts on JavaScript Closures
Closures allow us to write cleaner, more modular JavaScript code. The timer example is just one of many practical applications. I hope you find this article helpful. Happy learning :)
Subscribe to my newsletter
Read articles from The Syntax Node directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

The Syntax Node
The Syntax Node
I am a JavaScript Full Stack Developer with expertise in front-end frameworks like React and Angular, and back-end technologies such as Node.js and Express.