Scope Chain Theory
The scope chain is the lexical lookup path JavaScript uses to resolve identifiers, starting from the current scope and moving outward until a matching binding is found.
What it is
JavaScript uses lexical scoping, meaning variable resolution is based on where code is written, not where a function is called.
Each execution context has access to its own environment plus links to outer environments. These links create the scope chain.
Identifier lookup walks from the innermost environment to outer scopes and stops at the first match. If no binding exists, a ReferenceError is thrown.
Interview framing: define Scope Chain in one sentence, then explain one concrete runtime behavior and one common pitfall with a short code example.
How it works
- Step 1: code executes in a current lexical environment that contains local bindings.
- Step 2: when an identifier is referenced, the engine checks the current environment first.
- Step 3: if not found, the engine traverses outward through parent lexical environments.
- Step 4: resolution either finds a matching binding or ends at global scope with an unresolved reference error.
Common mistakes
Confusing lexical scope with dynamic scope
JavaScript does not resolve variables from the caller's scope. It resolves from where functions are defined.
Fix: Track where a function is declared to understand which outer bindings it can access.
Accidental shadowing
A local variable with the same name as an outer variable hides the outer binding and can cause confusing behavior.
Fix: Use intentional naming and smaller scopes to avoid accidental shadowing.
Expecting block scope from var
var is function-scoped, not block-scoped, so references can escape blocks in ways that differ from let and const.
Fix: Prefer let and const for predictable block-level scope behavior.
Interview questions
Common interview prompts with concise model answers.
Does JavaScript search global scope first?
No. Lookup starts from the innermost current scope and proceeds outward toward global scope.
const level = "global";
function outer() {
const level = "outer";
function inner() {
console.log(level); // "outer"
}
inner();
}Can scope chain change based on how a function is called?
No. Scope chain is lexical and fixed by declaration context, not invocation pattern.
How does scope chain relate to closures?
Closures preserve access to outer lexical environments, effectively extending scope-chain access beyond the outer function's execution.
Are imports part of scope resolution?
Yes. Module imports create bindings in module scope that participate in identifier resolution like other lexical bindings.
Related concepts
Continue with these concepts to strengthen your mental model.