Compile Ready
Module 3 · Scope & Closures

Lexical Scope & the Scope Chain

Intermediate7m read3m practice10m total
Lexical ScopeScope ChainClosuresName Resolution

Introduction

Lexical scope means JavaScript decides which variables a function can access by where that function is written in the source code, not where it is called.

The scope chain is the ordered set of environments JavaScript searches when resolving a name: local scope first, then outer lexical scopes, and finally global scope.

Why This Matters

This is the exact mental model interviewers expect before closures. A function passed across your program does not adopt the caller's local variables. It keeps access to the variables from the place it was created.

Theory

Lexical means source-position based

A function's accessible outer variables are determined at creation time from the surrounding source code. Calling the function from a different place does not change that outer environment. This is also called static scope.

The scope chain algorithm

When JavaScript reads an identifier like userId, it searches:

  1. the current function or block environment,
  2. the next outer lexical environment,
  3. continuing outward one environment at a time,
  4. the global environment,
  5. and if still not found, a direct read throws ReferenceError.

Shadowing

If an inner scope declares the same name as an outer scope, the inner binding shadows the outer one. Lookup stops at the first match. Shadowing is legal, but overusing it makes code harder to trace.

Lexical, not dynamic

QuestionJavaScript answer
Does a function use variables from where it is called?No
Does a function use variables from where it is written/created?Yes
Can an inner function see outer variables?Yes
Can an outer function see inner variables?No

Visual Diagrams

A function keeps its written scope chain
global scope
  label = 'global'

  makePrinter() scope
    label = 'outer'

    printer() scope
      read label
        |
        v
      finds makePrinter label first

callFromElsewhere() scope
  label = 'caller'
  printer() still does NOT use this label

The caller's local variables are not inserted into the callee's lexical scope chain.

Code Examples

Where a function is written matters

printer is called from callWithLocal, but it still reads label from makePrinter because that is where it was created.

Loading…

Shadowing stops lookup early

The inner id hides the outer id. JavaScript does not keep searching after it finds a local match.

Loading…

Output Prediction

Predict the output #1

javascript
1const label = 'global';
2
3function makePrinter() {
4 const label = 'outer';
5 return function () {
6 console.log(label);
7 };
8}
9
10function callWithLocal(fn) {
11 const label = 'caller';
12 fn();
13}
14
15callWithLocal(makePrinter());

Interview Questions

1What is lexical scope, and how is it different from dynamic scope?

Lexical scope means a function's accessible variables are determined by where the function is defined in the source code. Dynamic scope would mean variables are resolved based on the call stack or caller. JavaScript is lexically scoped: passing a function to another function does not make it see the caller's local variables.

Asked at:MicrosoftGoogleMetaNetflix

Follow-ups

  • How does this lead to closures?
  • What is variable shadowing?
2Describe the scope chain lookup process.

Lookup starts in the current local environment. If the name is not found, JavaScript checks the next outer lexical environment, then the next, until it reaches the global environment. If no binding exists, reading the identifier throws ReferenceError.

Quiz

1. A function's outer variables are determined by…

2. If an inner scope and outer scope both declare `value`, which one is read inside the inner scope?

Summary

  • Lexical scope is based on where functions and blocks are written, not where functions are called.
  • The scope chain searches local scope, then outer lexical scopes, then global scope.
  • Inner declarations can shadow outer declarations.
  • Closures work because functions keep access to their lexical scope chain.