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.
Loading...
See how the JavaScript scope chain works with an interactive visualization. Trace variable lookups across global, function, and block scopes from inner to outer step by step.
Loading visualization...
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.
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.
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.
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.
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.
Common interview prompts with concise model answers.
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();
}No. Scope chain is lexical and fixed by declaration context, not invocation pattern.
Closures preserve access to outer lexical environments, effectively extending scope-chain access beyond the outer function's execution.
Yes. Module imports create bindings in module scope that participate in identifier resolution like other lexical bindings.
Continue with these concepts to strengthen your mental model.
const x = "global"; function outer() { const y = "outer"; function inner() { const z = "inner"; console.log(z); console.log(y); console.log(x); console.log(w); } inner();}outer();no scopes yet
no lookup in progress
No output yet.