Closures & Scopehigh

Scope Chain & Lexical Scoping

JavaScript uses lexical (static) scoping: a variable's scope is determined by where it is written in the source code, not where the function is called from. Scope chain is the sequence of environments searched when looking up a variable.

Memory anchor

Scope chain is a series of nested Russian dolls — when looking for a variable, you open the smallest doll first, then the next bigger one, all the way to the giant global doll. The nesting is fixed at write time, not call time.

Expected depth

When a variable is referenced, the engine searches the current scope, then each outer scope in the chain, up to the global scope. ES6 introduced block scoping with let/const, creating new scopes for if blocks, for loops, and bare braces. Arrow functions create their own scope for variables but don't bind their own this/arguments — they inherit those from the enclosing lexical scope. with is a SyntaxError in strict mode; eval() still works but gets its own scope (cannot introduce variables into the enclosing scope), limiting its ability to alter the scope chain.

Deep — senior internals

The scope chain is implemented as a linked list of Environment Records in the spec. Outer references are set at function creation time (not call time), which is what makes lexical scoping work even across async gaps. V8 represents this as a Context chain (Context objects on the heap). The engine can optimize scope lookup by statically analyzing the chain at compile time and using direct slot access instead of name lookups, but dynamic code (eval, with) breaks this optimization — hence the strict mode prohibition.

🎤Interview-ready answer

JavaScript uses lexical scoping: scope is determined at write time, not call time. When resolving a variable, the engine walks from the innermost scope outward through the scope chain. This is what enables closures — an inner function's scope chain includes the outer function's scope even after the outer function returns.

Common trap

Dynamic scoping (where 'this' goes) is NOT the same as lexical scoping (where variables go). this is determined at call time by the call site; variable names are resolved at compile time via lexical scope. Confusing 'this lookup' with 'variable lookup' is a common mistake.

Related concepts