Back to JavaScript Notes
Topic #404

Closures

By the end of this lesson, you will be able to explain how a JavaScript closure keeps access to variables from the function that created it, even after that outer function has finished running.

What it is

A closure is a function bundled together with the variables from the scope where it was created. In JavaScript, when an inner function references variables from an outer function, the engine keeps those variables alive for the inner function. The outer function can return, but the inner function still remembers its surrounding scope.

Think of a closure as a backpack: the inner function carries the variables it needs from the outer function. Related terms include lexical scope, free variable, private state, and function factory.

Why it matters

  • Closures let you create private variables without exposing them to the global scope.
  • They are used in event handlers, timers, callbacks, and module patterns.
  • They help build reusable functions that remember configuration or state.
  • They are the foundation for many JavaScript patterns, including currying and memoization.

Syntax or steps

  1. Declare an outer function.
  2. Create a variable in the outer function's local scope.
  3. Return an inner function that uses that variable.
  4. Call the outer function once and store the returned inner function.
  5. Call the inner function later; it still has access to the outer variable.

Example

function makeCounter() {
  let count = 0;

  function increment() {
    count += 1;
    return count;
  }

  return increment;
}

const counter = makeCounter();

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

Part by part:

  • makeCounter() creates a local variable count.
  • increment() is the inner function. It reads and changes count.
  • return increment; gives back the inner function, not the value of count.
  • const counter = makeCounter(); stores the inner function. The outer function has finished, but count remains alive inside the closure.
  • Each call to counter() updates the same count.

Common mistakes

  • Calling the outer function every time: makeCounter()() creates a new closure each call, so the count restarts. Store the returned function instead.
  • Thinking closures are only for counters. They are also used for callbacks, event listeners, and private data.
  • Forgetting that closures keep variables alive. If a closure references a large object, that object may remain in memory longer than expected.
  • Using var in loops with callbacks. The callback may see the final loop value. Use let or create a new closure per iteration.

When to use it

Closures are useful when you need a small function with remembered state. Compare them with classes when the state and behavior become larger.

ApproachBest forExample
ClosureOne function with private statemakeCounter()
ClassMultiple methods and shared stateclass Counter { increment() { ... } }
Global variableQuick scripts onlylet count = 0;

Use a closure when you want simple private state. Use a class when you need several related methods. Avoid global variables when the state should not be changed from anywhere.

Practice

Guided exercise: write a function called makeGreeter(name) that returns a function. The returned function should accept a message and return Hello, name! message.

function makeGreeter(name) {
  return function(message) {
    return `Hello, ${name}! ${message}`;
  };
}

const greetAlice = makeGreeter("Alice");
console.log(greetAlice("How are you?"));

Expected output: Hello, Alice! How are you?

Challenge: create makeBankAccount(startingBalance) that returns an object with deposit(amount) and getBalance(). Hint: keep balance private inside the outer function.

Quick check

Question: Why does counter() keep increasing after makeCounter() has already returned?

Answer: Because the returned function closes over count, so the variable remains accessible and alive in the closure.

Summary

Closures are functions that remember the variables from the scope where they were created. They let JavaScript keep private state alive after an outer function finishes. Use closures for small, focused functions that need remembered data.

Want to go beyond the notes?

Join Coding Now Tech Institute's JavaScript course — live mentorship, real projects, and 100% placement support.

Enroll Now — Free Demo Available

Closures – FAQs

Quick answers about learning Closures in JavaScript.

This free note from Coding Now Tech Institute explains Closures in JavaScript — concept, syntax and worked code examples you can copy, run and revise before interviews.
Yes. Every JavaScript topic on Coding Now Tech Institute, including Closures, is 100% free with no signup required.
With focused practice, most students grasp Closures in 1–3 days from these notes; pairing it with Coding Now Tech Institute's mentor-led course takes you to job-ready depth faster.
Use the code examples in this note, then ask doubts for free on the Coding Now Tech Institute Community (/community) — expert instructors answer within 24 hours.
Call NowEnroll Now