JavaScript10 min read

JavaScript Closures Explained with Examples

Understanding closures in JavaScript: what they are, how they work, and practical use cases.

Alex Thompson
November 30, 2025
19.5k756

Closures are one of the most powerful and often misunderstood features of JavaScript. Understanding closures is essential for writing effective JavaScript code.

What is a Closure?

A closure is the combination of a function and the lexical environment within which that function was declared. In simpler terms, a closure gives you access to an outer function's scope from an inner function.

How Closures Work

In JavaScript, closures are created every time a function is created. The inner function has access to variables in three scopes: its own scope, the outer function's scope, and the global scope.

Practical Use Cases

Closures are used for data privacy, creating factory functions, in callbacks and event handlers, and for functional programming patterns.

#JavaScript#Closures#Functions#Scope

Common Questions & Answers

Q1

What is a closure in JavaScript?

A

A closure is a function that has access to variables in its outer (enclosing) lexical scope, even after the outer function has returned. It "closes over" the variables it needs from outer scopes.

javascript
function outer() {
  const message = 'Hello';
  
  function inner() {
    console.log(message); // Can access message
  }
  
  return inner;
}

const myFunction = outer();
myFunction(); // Logs: "Hello"
// inner() still has access to message even after outer() returned
Q2

How can closures be used for data privacy?

A

Closures can create private variables that cannot be accessed from outside the function, providing encapsulation similar to private properties in object-oriented programming.

javascript
function createCounter() {
  let count = 0; // Private variable
  
  return {
    increment() {
      count++;
      return count;
    },
    decrement() {
      count--;
      return count;
    },
    getCount() {
      return count;
    }
  };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount());  // 2
console.log(counter.count);       // undefined (private)
Q3

What is a common closure pitfall with loops?

A

A common pitfall is creating closures in loops with var. Since var is function-scoped, all closures reference the same variable. Use let (block-scoped) or create an IIFE to capture the correct value.

javascript
// Problem with var
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Logs: 3, 3, 3 (all closures reference the same i)

// Solution 1: Use let
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Logs: 0, 1, 2 (each closure has its own i)

// Solution 2: IIFE
for (var i = 0; i < 3; i++) {
  (function(j) {
    setTimeout(() => console.log(j), 100);
  })(i);
}
// Logs: 0, 1, 2