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
- Build three nesting levels; log which variables each level sees
- Prove
varloop leakage vsletcontainment - Shadow a global inside a function; verify outer value survives
- Extend makeCounter into makeCounter(step) honoring a step size
- 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.