</>
Skip to content
JavaScript lessons (41/64)

JavaScript — Scope

Scope = visibility rules

Where a variable can be seen from. Three arenas:

const global = "everywhere";          // global scope

function demo() {
    const fnOnly = "inside function"; // function scope

    if (true) {
        let blockOnly = "inside block";   // block scope (let/const)
    }
}
global
└── function scope
    └── block scope
        └── nested block…

Inside can see out; outside can't see in

const site = "codenatomy";

function greet() {
    const user = "Ada";
    console.log(`${user} @ ${site}`);   // both visible ✓
}

greet();
console.log(user);   // ReferenceError — born inside, dies inside

Lookup walks outward: current block → enclosing function → script → stop.

Block scope: let/const vs var

if (true) {
    var legacy = "leaks out";
    let modern = "stays in";
}
console.log(legacy);   // works 😕
console.log(modern);   // ReferenceError ✓

var ignores blocks — one more reason it's retired. Loops especially:

for (var i = 0; i < 3; i++);
console.log(i);   // 3 — leaked!

for (let j = 0; j < 3; j++);
// console.log(j) → Error — contained

Shadowing

Inner names temporarily cover outer ones:

let name = "outer";

function show() {
    let name = "inner";     // shadows the outer binding
    console.log(name);      // "inner"
}
show();
console.log(name);          // "outer" — untouched

Legal but confusing when accidental — rename instead.

Closures — functions remember home

A function keeps access to the scope where it was created:

function makeCounter() {
    let count = 0;                 // private to this closure
    return function () {
        count++;
        return count;
    };
}

const next = makeCounter();
next();   // 1
next();   // 2   ← count survived between calls!

count lives on inside the returned function's memory — unreachable from outside, perfect for private state. You'll meet closures everywhere: event handlers, React hooks, module patterns.

Global hygiene

Script-level let/const stay per-script; but any assignment to an undeclared name creates a true global:

function leak() {
    oops = "implicit global";   // no declaration → leaks everywhere
}

Strict mode (own lesson) turns that into an error.

Mini Practice

  1. Build three nesting levels; log which variables each level sees
  2. Prove var loop leakage vs let containment
  3. Shadow a global inside a function; verify outer value survives
  4. Extend makeCounter into makeCounter(step) honoring a step size
  5. Create two independent counters from one factory — explain why they don't share

Next: hoisting →

Related Topics

Frequently Asked Questions about Scope

What is Scope in JavaScript?

Scope is a fundamental concept in JavaScript. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn Scope?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Scope.

Why is Scope important in JavaScript?

Scope is essential for JavaScript development. Understanding this concept will help you write better code and solve real-world problems more effectively.