Classic JS Tutorial | JS in VS 2026 | JS Examples | jQuery
⚡ Lesson 14 of 30

Scope & Closures

Understand variable scope, the scope chain, lexical environments, and the power of closures.

Block Scope with let/const

let and const are block-scoped — they only exist inside the {} they are declared in:

{
  let x = 10;
  const y = 20;
  console.log(x, y); // 10 20
}
// console.log(x); // ReferenceError!

Function Scope

Variables declared with var (or function parameters) are scoped to the enclosing function:

function greet() {
  var message = "Hello!";
  console.log(message); // "Hello!"
}
greet();
// console.log(message); // ReferenceError!

The Scope Chain

Inner functions can access variables from outer functions — this forms the scope chain:

function outer() {
  const x = 10;
  function inner() {
    const y = 20;
    console.log(x + y); // 30 — x from outer scope
  }
  inner();
}
outer();

Closures

A closure is a function that remembers the variables from the scope where it was created, even after that scope has finished executing:

function makeCounter(start = 0) {
  let count = start; // "closed over"
  return {
    increment() { count++; },
    decrement() { count--; },
    value()     { return count; },
  };
}

const counter = makeCounter(10);
counter.increment();
counter.increment();
console.log(counter.value()); // 12

Practical Closure: Memoization

Closures enable powerful patterns like memoization (caching expensive results):

function memoize(fn) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (key in cache) return cache[key];
    return (cache[key] = fn(...args));
  };
}

const factorial = memoize(n => n <= 1 ? 1 : n * factorial(n - 1));
console.log(factorial(6)); // 720
← Lesson 13🏠 HomeLesson 15 →