Facebook Pixel

How the JavaScript Engine Resolves Variables

Variable resolution is a walk up the scope chain. Here is the exact process the engine follows.

How the JavaScript Engine Resolves Variables

When you reference a variable in JavaScript, the engine follows a precise process to find its value. Understanding this process makes scope and closures click.

The Resolution Process

  1. Check the current lexical environment's environment record.
    • If the variable is found, return its value.
    • If it is in the TDZ (for let/const), throw ReferenceError: Cannot access 'x' before initialization.
  2. Follow the outer reference to the parent lexical environment.
    • Repeat step 1.
  3. Continue up the chain until the global environment is reached.
  4. If not found in the global environment:
    • For a read: throw ReferenceError: x is not defined.
    • For a write with var (non-strict): create a global variable (sloppy mode only).
    • For a write (strict mode): throw ReferenceError.

Example Walkthrough

const globalVar = "G"; function outer() { const outerVar = "O"; function inner() { console.log(outerVar); // resolution here } inner(); } outer(); `` When `inner` runs and references `outerVar`: 1. `inner`'s environment record: has no `outerVar`. 2. Follow outer reference to `outer`'s environment. 3. `outer`'s environment record: has `outerVar` = "O". Found. Return "O". ### Performance Note The engine resolves variables at parse time when possible. It knows the depth of each variable in the scope chain and can access it directly without walking. This is why lexical scope is fast. ### `var` and the Global Object In non-strict mode, assigning to an undeclared variable creates a global property: ```js function foo() { undeclaredVar = 5; // creates window.undeclaredVar in sloppy mode } foo(); console.log(undeclaredVar); // 5 `` In strict mode, this throws `ReferenceError`. Always use strict mode or modules to avoid this. ### `typeof` Is Special `typeof` does not throw for undeclared variables: ```js typeof undeclared; // "undefined" (no error) `` This is a spec exception to allow safe feature detection. ### The Takeaway Variable resolution: check the current environment, follow outer references up to global, and throw `ReferenceError` if not found. `let`/`const` in the TDZ throw a specific error. `typeof` is a safe exception. In sloppy mode, writing to an undeclared variable creates a global; strict mode throws.

It checks the current lexical environment's environment record. If not found, it follows the outer reference to the parent environment and repeats. This continues up to the global scope. If not found, it throws ReferenceError.

In sloppy (non-strict) mode, it creates a global property on window. In strict mode (and ES modules), it throws ReferenceError. Always use strict mode to catch this bug.

It is a spec exception to allow safe feature detection. typeof undeclared returns 'undefined' instead of throwing ReferenceError. This lets you check if a global API exists without crashing.

ReferenceError: Cannot access 'x' before initialization. The variable is in the environment record but marked as uninitialized until the declaration line.

No. The engine resolves variables at parse time when possible, knowing the depth of each variable in the chain. It can access variables directly without walking at runtime. Lexical scope is fast.

Ready to master React completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.