DEV Community

Cover image for Closures and Scope in JavaScript: Lexical Scope, Closures, and IIFE Explained
Sharique Siddiqui
Sharique Siddiqui

Posted on

Closures and Scope in JavaScript: Lexical Scope, Closures, and IIFE Explained

When learning JavaScript, one of the most important — and sometimes confusing — concepts you’ll encounter is scope and how it interacts with closures. These ideas determine how variables are accessed, preserved, and protected throughout your code. Understanding them not only helps you avoid errors but also unlocks powerful programming patterns for cleaner, more modular applications.

Let’s break it down step by step.

1. What is Scope?

Scope answers the question: “Where can I access a variable?”

JavaScript uses lexical (or static) scope, which means that the scope of a variable is determined by where you write the code, not where it is executed.

This differs from dynamic scope (used in some other languages), where variable access can change depending on the call stack at runtime.

Example:
js
function outer() {
  let outerVar = "I'm from outer";

  function inner() {
    console.log(outerVar);
  }

  inner();
}

outer(); // "I'm from outer"
Enter fullscreen mode Exit fullscreen mode

Here, inner can access outerVar because of lexical scope. Even though the function is called inside outer, what really matters is where it was defined.

2. What is a Closure?

A closure is created when a function "remembers" its lexical scope, even if it’s called outside of that original scope.

That means inner functions can "close over" variables from their parent functions long after the parent has finished executing.

Example:
js
function counter() {
  let count = 0;

  return function () {
    count++;
    return count;
  };
}

const increment = counter();

console.log(increment()); // 1
console.log(increment()); // 2
console.log(increment()); // 3
Enter fullscreen mode Exit fullscreen mode

Why does this work?

  • The counter function finishes execution.
  • Normally, we expect its local variables like count to disappear.
  • But the returned inner function remembers the scope where it was created.
  • That preserved environment + function = closure. Closure is the mechanism that makes features like private data, stateful functions, and function factories possible.

3. IIFE (Immediately Invoked Function Expression)

An IIFE is a function that runs as soon as it is defined. It’s often wrapped in parentheses to turn the function into an expression and then immediately executed:

js
(function () {
  let message = "This is private!";
  console.log(message);
})();
Enter fullscreen mode Exit fullscreen mode

Why use IIFE?

  • It creates a new, temporary scope.
  • Variables inside an IIFE cannot leak into the global scope.
  • It was historically important before ES6 let and const introduced block scope, but even today, it’s a neat trick to avoid polluting global namespaces.

IIFEs are also handy when paired with closures to create self-contained modules:

js
const myModule = (function () {
  let privateVar = 0;

  return {
    increment: function () {
      privateVar++;
      return privateVar;
    },
    reset: function () {
      privateVar = 0;
    }
  };
})();

console.log(myModule.increment()); // 1
console.log(myModule.increment()); // 2
myModule.reset();
console.log(myModule.increment()); // 1
Enter fullscreen mode Exit fullscreen mode

Here, privateVar is inaccessible directly from outside but preserved inside the closure, giving us encapsulation similar to classes in other languages.

4. Putting It All Together

  • Lexical scope: Functions access variables based on where they were written.
  • Closures: Functions "keep alive" their surrounding environment, even after the outer function has finished running.
  • IIFE: Functions that run immediately and create isolated scopes, often used with closures to avoid global scope pollution.

Final Thoughts

Closures and scope form the backbone of JavaScript’s functional capabilities. They enable patterns like data privacy, currying, event handlers, and module design. Once you understand lexical scope and how functions capture their surrounding environment, you’ll find closures to be one of the most powerful concepts at your disposal.

Stay tuned for more insights as you continue your journey into the world of web development!

Check out theYouTubePlaylist for great JavaScript content for basic to advanced topics.

Please Do Subscribe Our YouTube Channel for clearing programming concept and much more ...CodenCloud

Top comments (0)