DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. Scope Chain and Lexical Scoping in JavaScript
XLinkedInReddit
Frontend Engineering

Scope Chain and Lexical Scoping in JavaScript

D
DevPrep Team
February 10, 2026·2 min read·0
Table of Contents
  • Types of Scope
  • Global Scope
  • Function Scope
  • Block Scope (let/const)
  • Lexical Scoping
  • The Scope Chain
  • Temporal Dead Zone (TDZ)
  • Module Scope
  • Common Gotchas

Scope determines where variables are accessible. Understanding the scope chain is essential for closures, hoisting, and debugging.

Types of Scope

Global Scope

var globalVar = "I'm global";
let globalLet = "I'm also global";
// Accessible everywhere

Function Scope

function myFunc() {
  var functionScoped = "Only inside myFunc";
  // var is function-scoped
}
console.log(functionScoped); // ReferenceError!

Block Scope (let/const)

if (true) {
  let blockScoped = "Only inside this block";
  const alsoBlock = "Same here";
  var notBlock = "I escape the block!"; // var ignores block scope
}
console.log(blockScoped); // ReferenceError!
console.log(notBlock);    // "I escape the block!"

Lexical Scoping

JavaScript uses lexical (static) scoping — scope is determined by where code is WRITTEN, not where it's called.

const x = 10;

function outer() {
  const x = 20;
  
  function inner() {
    console.log(x); // 20 — looks up to where inner is DEFINED
  }
  
  inner();
}

function another() {
  const x = 30;
  outer(); // inner still prints 20, not 30
}

The Scope Chain

const global = "global";

function outer() {
  const outerVar = "outer";
  
  function middle() {
    const middleVar = "middle";
    
    function inner() {
      const innerVar = "inner";
      
      // Scope chain: inner → middle → outer → global
      console.log(innerVar);  // Found in inner scope
      console.log(middleVar); // Found in middle scope
      console.log(outerVar);  // Found in outer scope
      console.log(global);    // Found in global scope
    }
    inner();
  }
  middle();
}

Temporal Dead Zone (TDZ)

// let and const are hoisted but NOT initialized
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 5;      // TDZ ends here

// var IS initialized (to undefined)
console.log(y); // undefined (not an error!)
var y = 5;

Module Scope

// Each module has its own scope
// Variables don't leak to global
const moduleVar = "Only accessible in this module";

// Must explicitly export to share
export const shared = "Accessible to importers";

Common Gotchas

  • Variables declared without var/let/const become global (sloppy mode)
  • Function declarations are hoisted entirely; function expressions are not
  • Block-scoped variables in loops create a new binding per iteration
  • The scope chain is fixed at function creation, not execution

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • Types of Scope
  • Global Scope
  • Function Scope
  • Block Scope (let/const)
  • Lexical Scoping
  • The Scope Chain
  • Temporal Dead Zone (TDZ)
  • Module Scope
  • Common Gotchas

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.