Scope and the Scope Chain
JavaScript uses lexical (static) scoping — a function's access to variables is determined by where it's written in the code, not by where it's called from.
let outer = "I'm outer";
function outerFn() {
let inner = "I'm inner";
function innerFn() {
console.log(outer, inner); // both accessible
}
innerFn();
}
outerFn();
There are three main scope levels: global scope (accessible everywhere), function scope (created by every function call), and block scope (created by {} for let/const, though not for var).
When the engine looks up a variable name and doesn't find it in the current scope, it walks up the scope chain — checking each enclosing scope in order — until it finds a match or reaches the global scope and throws a ReferenceError. This chain is fixed at the time the function is defined, which is exactly what makes closures (the next lesson) possible.