Understanding JavaScript Closures Through a Timer Example

The Syntax NodeThe Syntax Node
3 min read

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:

  1. Start the timer to begin tracking time.

  2. Pause the timer to stop tracking temporarily.

  3. Reset the timer to set elapsed time back to zero.

  4. 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

  1. Private Variables: The elapsedTime and intervalId variables are private to the createTimer function. They are not directly accessible from outside the timer, ensuring better encapsulation.

  2. Public Methods: The methods start, pause, reset, and checkTime 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

  1. Encapsulation: The elapsedTime and intervalId variables are private to each timer instance, ensuring data is protected from accidental external manipulation.

  2. Independent Instances: Each call to createTimer creates a new instance with its own private state. Changes to one timer do not affect another.

  3. 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 :)

0
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.