← Back to JavaScript Course | Chapter 6: Functions Advanced | Lesson 1 of 8

JS Closures

What Is a Closure?

A closure happens when a function remembers variables from its outer scope. The inner function can use those variables later. This is possible because JavaScript functions keep a live reference to their enclosing scope, not a snapshot of it, so the variables persist as long as the closure does.

Example: What Is a Closure?

javascript
function outer() {
  const message = "Hello";
  function inner() {
    console.log(message); // remembers outer's variable
  }
  return inner;
}
const greet = outer();
greet();

Private Data

Closures can keep data private. Code outside the closure cannot directly access the hidden variable. This is a common way to implement things like a counter that increments correctly even though no other code can read or overwrite its internal count directly.

Example: Private Data

javascript
function makeCounter() {
  let count = 0; // private, not accessible outside
  return function () {
    count++;
    return count;
  };
}
const counter = makeCounter();
console.log(counter());
console.log(counter());

Closures With Parameters

Each call can create a separate closure. The stored values do not have to be shared. Because each function call gets its own execution context, a factory function that returns a closure produces independent, non-interfering instances.

Example: Closures With Parameters

javascript
function makeMultiplier(factor) {
  return (n) => n * factor;
}
const double = makeMultiplier(2);
const triple = makeMultiplier(3);
console.log(double(5), triple(5)); // independent closures

Practical Use

Closures are useful for counters, factories, and functions that need remembered settings. A closure that captures a database connection or API key, for instance, lets you expose a clean function API without re-passing that configuration on every call.

Example: Practical Use

javascript
function createApiClient(apiKey) {
  return function fetchData() {
    console.log("Using key:", apiKey);
  };
}
const client = createApiClient("secret123");
client();

Practice

Try creating closures that remember a number or a name. Try writing a makeCounter() function that returns increment/decrement functions sharing one hidden counter variable.

Example: Practice

javascript
function makeCounter() {
  let count = 0;
  return {
    increment: () => ++count,
    decrement: () => --count,
  };
}
const c = makeCounter();
console.log(c.increment(), c.increment(), c.decrement());
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.