Closures

A clear, in-depth guide to closures in JavaScript — with worked examples, common pitfalls, and a practice quiz.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

💡 Running Code Locally: While this online editor runs real JavaScript, some advanced examples may have limitations. For the best experience:

🎒 Real-World Analogy: A closure is like a backpack that remembers :

Closures are the heart and soul of JavaScript.

Every professional JavaScript developer — especially those working in React, Node.js, or complex web apps — uses closures every single day, often without noticing.

By the end of this lesson, closures will feel completely natural.

Before closures make sense, you MUST understand scope.

📌 Variables are resolved based on WHERE the code was written, not where it is executed.

Anything declared outside a function is global.

Accessible everywhere. Dangerous for large apps.

Function boundaries matter a lot in closures.

Block scoping is essential for fixing closure bugs (you'll see later).

Inner functions access variables declared where they were written.

A function that "remembers" variables from its outer scope — even after the outer function has returned.

This is the single most important concept in JavaScript.

Even though outer() has finished executing, the inner function keeps access to:

JavaScript has no private keyword (until ES2020 classes). Before that, closures were the ONLY way to hide data.

This is true encapsulation — impossible with global variables.

Closures let you preload data into functions.

Event handlers, timeouts, and interactive websites heavily rely on closures.

Even after setupButton finishes, the inner arrow function still knows:

That's why closures are essential for UI programming.

Closures keep variables alive during async operations.

Even though loadUser has returned long before the API finishes, the .then() callback remembers prefix .

Memoization = caching results so future calls are instant.

You've mastered one of the hardest concepts in JavaScript. Understanding closures puts you in the top tier of JavaScript developers.

Up next: Prototypes & Classes — understanding how object-oriented programming works in JS! 🧬

Practice quiz

What is a closure in JavaScript?

  • A way to close a browser window
  • A function with no parameters
  • A function that remembers variables from its outer scope even after the outer function has returned
  • A loop that runs forever

Answer: A function that remembers variables from its outer scope even after the outer function has returned. The lesson defines a closure as a function that remembers variables from its outer scope, even after the outer function has returned.

What kind of scope does JavaScript use to resolve variables?

  • Lexical scope
  • Dynamic scope
  • Random scope
  • Block-only scope

Answer: Lexical scope. JavaScript uses lexical scope: variables are resolved based on WHERE the code was written, not where it is executed.

Given: function outer() { const name = 'Boopie'; function inner() { console.log(name); } return inner; } outer()(); What does this log?

  • undefined
  • ReferenceError
  • null
  • 'Boopie'

Answer: 'Boopie'. Through lexical scope, inner() accesses name from where it was written, so calling outer()() logs 'Boopie'.

In the createCounter example, what does counter.count return after two increments?

  • 2
  • undefined
  • 0
  • 1

Answer: undefined. count is a private variable trapped in the closure, so counter.count returns undefined; only the returned methods can reach it.

Which statement about a 'var' variable declared inside a function is correct?

  • It lives inside the function only (function scope)
  • It is global
  • It is block scoped to the nearest if
  • It cannot be reassigned

Answer: It lives inside the function only (function scope). var variables live inside the function only, which is why console.log(x) outside the function throws an error.