DEV Community

Samaresh Das
Samaresh Das

Posted on

Why closures finally clicked for me after 2 years

Closures aren't magic, but for two years, I genuinely thought they were dark sorcery.

If you've ever felt utterly baffled by how a function remembers variables from its parent scope long after the parent has returned, you're definitely not alone. This is about that "aha!" moment when JavaScript closures stopped being an abstract concept and started making actual sense to me.

My journey was a mix of copying code, using frameworks that subtly abstracted them, and nodding vaguely when someone mentioned "lexical environment." I knew they existed, but truly understanding their power felt like trying to catch smoke. I pictured some kind of JavaScript ghost holding onto variables. 😂

The core idea, once it finally clicked, is surprisingly simple: A closure is when a function "remembers" its lexical environment even when that function is executed outside its original scope. Think of it as a function carrying a little backpack of variables from where it was created, a memory of its birthplace. This "lexical environment" just means the variables and functions that were available where the function was declared.

Let's look at a classic example that finally made it click for me – a simple counter function:

function createCounter() {
  let count = 0; // This variable is part of createCounter's lexical environment
  return function() { // This inner function forms a closure
    count++;
    return count;
  };
}

const myCounter = createCounter();
console.log(myCounter()); // Output: 1
console.log(myCounter()); // Output: 2
Enter fullscreen mode Exit fullscreen mode

Notice how myCounter continues to increment count, even though createCounter() has already finished executing and its execution context has technically "popped off the stack." The inner function returned by createCounter "closed over" the count variable. It keeps a persistent reference to it, allowing its value to be maintained across multiple calls.

Why is this seemingly abstract concept incredibly useful in web development?

  • Data Privacy/Encapsulation: You can create "private" variables that only the inner function can access, protecting them from external modification and preventing global scope pollution.
  • Factory Functions: Closures let you generate custom functions with pre-configured settings, making your code more flexible and reusable. For instance, a function that creates different types of validators.
  • Stateful Functions & Event Handlers: They're crucial for remembering context for callbacks in asynchronous operations or when attaching event listeners. Each event handler can have its own persistent data.

Another quick example using a "factory" for event listeners – a common pattern (though frameworks often abstract this):

function createButtonClickHandler(buttonId) {
  // This inner function closes over 'buttonId'
  return function() {
    console.log(`Button ${buttonId} was clicked!`);
    // We can now perform actions specific to this buttonId
  };
}

// Imagine having buttons with IDs 'saveBtn', 'deleteBtn'
const saveHandler = createButtonClickHandler('saveBtn');
const deleteHandler = createButtonClickHandler('deleteBtn');

// In a real app, you'd attach these to actual DOM elements:
// document.getElementById('saveBtn').addEventListener('click', saveHandler);

// Simulating clicks for demonstration:
saveHandler();   // Output: "Button saveBtn was clicked!"
deleteHandler(); // Output: "Button deleteBtn was clicked!"
Enter fullscreen mode Exit fullscreen mode

Each handler function remembers its own buttonId from when it was created. That's the closure doing its job, providing isolated state for each callback.

The single biggest takeaway is that functions don't just execute code; they also remember the environment in which they were born. This memory is what a closure is all about.

Understanding these core JavaScript concepts like closures isn't just academic; it directly translates into writing more robust, maintainable, and efficient code for the websites I build. It's especially useful when architecting complex client-side applications or custom utility functions for freelance projects. If you need a hand bringing a web project to life, you can learn more about my work here: https://hire-sam.vercel.app/

Save this if useful! 💡

javascript #webdev #frontend #programming

Top comments (0)