Apply Now Apply Now Apply Now
header_logo
Post thumbnail
JAVASCRIPT

Lexical Scope in JavaScript: A Simple and Easy Guide

By Jebasta

Ever declared a variable, used it a few functions deep, and gotten a confusing “not defined” error even though you swore you declared it? That confusion almost always traces back to one concept: lexical scope.

Lexical scope in JavaScript means a variable’s accessibility is determined by where it’s physically written in your code, not by how or where a function gets called.

JavaScript decides which variables a function can access by looking at the code’s structure at write-time, which is exactly why the language stays predictable and debuggable even as programs grow large.

This guide breaks down Lexical Scope in JavaScript in plain language: what it actually means, how it works, how it powers closures, and where beginners most often get confused.

Table of contents


  1. TL;DR Summary
  2. Understanding Scope Before Lexical Scope
    • What Is Scope?
    • Scopes in JavaScript
    • Scopes in JavaScript at a Glance
  3. What Is Lexical Scope in JavaScript?
  4. Lexical Scope in JavaScript vs Dynamic Scope
  5. Why Lexical Scope Is Predictable
  6. Nested Functions and Lexical Scope in JavaScript
  7. Invalid Access Example
  8. Lexical Environment and the Scope Chain in JavaScript
  9. Lexical Scope and Closures
  10. Lexical Scope with var, let, and const
    • var and Lexical Scope
    • let and const
  11. Common Lexical Scope Confusions
    • Confusion 1: Function Call vs Function Definition
    • Confusion 2: Shadowing Variables
  12. Arrow Functions and Lexical Scope
  13. Real-World Importance of Lexical Scope
  14. Wrapping it up
  15. FAQs
    • 1) Is Block Scope the Same as Lexical Scope?
    • 2) Does Var Follow Lexical Scope?
    • 3) Do Arrow Functions Follow Lexical Scope?
    • 4) What Is The Importance Of Lexical Scope In JavaScript?

TL;DR Summary

  • What it is: a variable’s accessibility depends on where it’s written in the code, fixed at write-time, not at the moment a function runs
  • The three scope types: global, function, and block, each with different rules for what’s visible where
  • Why it matters: Lexical Scope in JavaScript is the entire mechanism behind closures, and it’s one of the most commonly tested interview concepts
  • The opposite approach: dynamic scope (used by some other languages) determines scope based on how a function is called, not where it’s written, unlike Lexical Scope in JavaScript
  • Where beginners trip up: confusing function definition location with function call location, and accidentally shadowing variables

Understanding Scope Before Lexical Scope

Before getting into Lexical Scope in JavaScript specifically, it helps to understand what “scope” means in general terms first.

What Is Scope?

Scope determines where in your code a variable or function can actually be accessed. In short, scope answers questions like:

  • Where can I use this variable?
  • Where does this function actually exist?
  • Why can’t JavaScript find a variable I know I declared?

In JavaScript, scope exists to keep variables from colliding with each other. It’s also the general idea Lexical Scope in JavaScript builds on directly, keeping your code organized and safe from accidental overwrites.

Also read: A Comprehensive Guide On Objects, Methods, and Classes In JavaScript

Scopes in JavaScript

Scopes in JavaScript

Scopes in JavaScript at a Glance

Scope TypeWhere Variables Are VisibleDeclared With
GlobalEverywhere in your codeAny declaration outside functions/blocks
FunctionOnly inside the function where it’s declaredvar, let, or const inside a function
BlockOnly inside the specific { } block where it’s declaredlet or const inside an if, for, or similar block

1. Global Scope

Variables declared outside all functions or blocks belong to the global scope.

let siteName = "GUVI";
function showSite() {
  console.log(siteName);
}
showSite();
  • siteName is accessible everywhere in the file
  • Overusing global variables invites bugs, since anything can modify them
  • Keep global scope usage minimal

2. Function Scope

Variables declared inside a function can’t be accessed from outside that function.

function calculate() {
  let total = 100;
  console.log(total);
}
calculate();
// console.log(total); // ReferenceError

This isolation prevents accidental overwrites and keeps your code safer overall.

Also read: 45 JavaScript Questions Towards Better Interviews

3. Block Scope

Variables declared with let or const inside a block (like an if statement) are only visible within that block.

if (true) {
  let score = 90;
  console.log(score);
}
// console.log(score); // Error

Block scope is a big part of why modern JavaScript is easier to predict and debug than older var-based code.

Also read: From Tutorials To Real Code: Building While You Learn JavaScript

What Is Lexical Scope in JavaScript?

Lexical scope in JavaScript refers to the rule that a variable’s accessibility is determined by where it is written in the source code.

In simpler words:

JavaScript uses the code structure to determine the variable scope, and not the execution of functions.

This means:

  • Scope is fixed at the time of writing the code
  • Functions remember their surrounding environment
  • The scope does not change dynamically

Also read: Best JavaScript Roadmap Beginners Should Follow

Lexical Scope in JavaScript vs Dynamic Scope

This distinction comes up constantly in interviews, and it’s worth understanding clearly rather than just memorizing the term “lexical.”

AspectLexical (Static) ScopeDynamic Scope
Determined byWhere the code is writtenHow the function is called
When it’s fixedAt write-time (before the code even runs)At runtime, based on the call stack
Used byJavaScript, most modern languagesOlder languages like some Lisp dialects, Bash
PredictabilityHigh, you can tell scope just by reading the codeLower, scope can change depending on the call path

JavaScript exclusively uses Lexical Scope. This is exactly why you can read a function’s code and know precisely which variables it can access, without needing to trace every possible place that function might get called from.

Also read: Best Tips and Tricks for JavaScript Debugging Skills [2026]

Why Lexical Scope Is Predictable

Unlike some languages that determine scope at runtime, JavaScript uses static scoping, also known as lexical scoping.

Why Lexical Scope is Predictable

This makes JavaScript:

  • Easier to reason about
  • Easier to debug
  • Safer when it comes to large applications.

When developers ask what is lexical scope in JavaScript, they are really asking how JavaScript maintains consistency and structure in complex programs.

Also read: Best Tips and Tricks for JavaScript Debugging Skills [2026]

Nested Functions and Lexical Scope in JavaScript

Lexical Scope in JavaScript really shows its value once functions get nested inside each other.

function parent() {
  let parentVar = "I am from parent";
  function child() {
    let childVar = "I am from child";
    console.log(parentVar);
    console.log(childVar);
  }
  child();
}
parent();

Why this works:

  • child() is physically written inside parent()
  • That lets child() reach up and read parentVar
  • Scope only flows outward, never inward, a parent function can never access variables declared inside its child

Also read: Best JavaScript Frameworks in 2026

Invalid Access Example

function parent() {
  function child() {
    let secret = "hidden";
  }
  // console.log(secret); // Error
}

This fails because scope only flows outward. parent() has no way to reach into child() and read secret, since secret was never declared in parent()‘s own scope or anywhere above it.

GUVI Ad

GUVI Ad

Lexical Environment and the Scope Chain in JavaScript

Every time JavaScript runs a piece of code, it builds something called a lexical environment, the backbone of Lexical Scope in JavaScript.

A lexical environment holds:

  • Variable declarations
  • Function declarations
  • A reference to the outer lexical environment it’s nested inside

Each function’s lexical environment links back to its parent’s, and that chain of links is what’s actually called the scope chain.

When JavaScript can’t find a variable in the current scope, it walks up this chain, environment by environment, until it finds the variable or runs out of chain and throws a ReferenceError.

Also read: Best 5 Reasons to learn JavaScript in regional languages

Lexical Scope and Closures

One of JavaScript’s most powerful features, closures, depends entirely on Lexical Scope in JavaScript to work.

function greeting(name) {
  return function () {
    console.log("Hello, " + name);
  };
}
const greetUser = greeting("Vishalini");
greetUser();

What’s happening internally:

  • greetUser remembers name, even though greeting() already finished running
  • The outer function’s job is technically done, but its lexical environment isn’t thrown away
  • The inner function keeps a live reference to that outer environment
  • This is the exact memory mechanism that lexical scope makes possible

Without understanding Lexical Scope in JavaScript, closures feel like pure magic. Once you do understand it, they’re just a predictable consequence of how JavaScript remembers where functions were defined.

If you want to explore JavaScript through a self-paced course, try HCL GUVI’s JavaScript course.

Lexical Scope with var, let, and const

var and Lexical Scope

  • Function-scoped, not block-scoped
  • Can produce genuinely confusing, unpredictable behavior in loops for (var i = 0; i < 3; i++) { console.log(i); } console.log(i); // 3

let and const

  • Block-scoped
  • Safer and the modern default choice
  • Strongly preferred in real, current codebases for (let i = 0; i < 3; i++) { console.log(i); } // console.log(i); Error

With let and const, Lexical Scope in JavaScript behaves far more intuitively than it does with var.

Common Lexical Scope Confusions

Confusion 1: Function Call vs Function Definition

let value = 10;
function display() {
  console.log(value);
}
function run(fn) {
  let value = 20;
  fn();
}
run(display); // logs 10

Why 10, not 20? Because lexical scope depends on where display was defined (the global scope, where value is 10), not where it’s called from (inside run, where a different value happens to be 20).

GUVI Ad

Confusion 2: Shadowing Variables

let count = 5;
function example() {
  let count = 10;
  console.log(count); // 10
}
example();
console.log(count); // 5

This is called variable shadowing, the inner count temporarily hides the outer one within its own scope, and it’s entirely a consequence of Lexical Scope in JavaScript.

Also read: Master Backend Development With JavaScript | Become a Pro

GUVI Ad

Arrow Functions and Lexical Scope

Arrow functions follow the same Lexical Scope in JavaScript rules as regular functions, plus a bit more.

They additionally inherit:

  • Lexical this, meaning this inside an arrow function refers to this from the surrounding code, not its own
  • Lexical arguments, in the sense that arrow functions don’t have their own arguments object and instead see the enclosing scope’s let language = “JavaScript”; const showLang = () => { console.log(language); }; showLang();

Real-World Importance of Lexical Scope

  • Helps write clean and well-structured JavaScript code
  • Prevents common errors like undefined variables
  • Controls where variables can be accessed
  • Makes debugging easier and faster
  • Essential for understanding closures
  • Plays a key role in asynchronous JavaScript
  • Widely used in modern frameworks and libraries
  • Improves code scalability and maintainability
  • Frequently asked concept in JavaScript interviews

Kickstart your Full Stack Development journey by enrolling in HCL GUVI’s certified Full Stack Development Course with Placement Assistance where you will master the MERN stack (MongoDB, Express.js, React, Node.js) and build interesting real-life projects.

Wrapping it up

When learning about lexical scope in JavaScript, it can seem abstract at first. However, once you have learned what it is, the language is much easier to reason about. Many bugs will go away simply because you will understand where variables are stored and how they can be resolved/located by the JavaScript engine.

If you understand what lexical scoping is in JavaScript, you will be able to do more than just write code; you will be able to think like a JavaScript engine.

FAQs

1) Is Block Scope the Same as Lexical Scope?

No, Lexical Scope is determined mostly by where you initially declare the variable in your code, whereas Block Scope is determined by where that variable exists in the code before or after it is actually declared.

2) Does Var Follow Lexical Scope?

Yes, but there is also Function Scope associated with var Declared Variables which could sometimes lead to non-predictive behavior.

3) Do Arrow Functions Follow Lexical Scope?

Yes, Arrow Functions utilize Lexical Scope, but they also inherit Lexical This.

4) What Is The Importance Of Lexical Scope In JavaScript?

Predictability of Code, Reduced Bugs, Closures.

Success Stories

Did you enjoy this article?

Learn with HCL GUVI

Schedule 1:1 free counselling

Similar Articles

Loading...
Get in Touch
Chat on Whatsapp
Request Callback
Share logo Copy link
Table of contents Table of contents
Table of contents Articles
Close button

  1. TL;DR Summary
  2. Understanding Scope Before Lexical Scope
    • What Is Scope?
    • Scopes in JavaScript
    • Scopes in JavaScript at a Glance
  3. What Is Lexical Scope in JavaScript?
  4. Lexical Scope in JavaScript vs Dynamic Scope
  5. Why Lexical Scope Is Predictable
  6. Nested Functions and Lexical Scope in JavaScript
  7. Invalid Access Example
  8. Lexical Environment and the Scope Chain in JavaScript
  9. Lexical Scope and Closures
  10. Lexical Scope with var, let, and const
    • var and Lexical Scope
    • let and const
  11. Common Lexical Scope Confusions
    • Confusion 1: Function Call vs Function Definition
    • Confusion 2: Shadowing Variables
  12. Arrow Functions and Lexical Scope
  13. Real-World Importance of Lexical Scope
  14. Wrapping it up
  15. FAQs
    • 1) Is Block Scope the Same as Lexical Scope?
    • 2) Does Var Follow Lexical Scope?
    • 3) Do Arrow Functions Follow Lexical Scope?
    • 4) What Is The Importance Of Lexical Scope In JavaScript?