Skip links

Table of Contents

Lexical Scope in JavaScript

When writing JavaScript, variable accessibility is determined by where a function is defined. This behavior is called lexical scoping. JavaScript follows a lexical scope model, meaning it resolves variable lookups based on where the function was declared in the source code, not where it is executed.

TL;DR

  • Lexical scope determines variable accessibility based on where a function is declared, not where it is called.
  • Closures are functions that remember their lexical scope even after execution.
  • Understanding scopes in JavaScript helps in writing maintainable and optimized code.
  • This article explains scope types, variable lookups, closure usage, and real-world examples.

Why Should You Care?

Understanding lexical scope is essential because:

  • It prevents unintended variable access issues.
  • It helps in writing modular and reusable code.
  • It is the foundation of closures, one of JavaScript’s most powerful features.

What is Lexical Scope in JavaScript?

Lexical Scope vs. Dynamic Scope

Before diving deep, let’s differentiate lexical scope from dynamic scope:

FeatureLexical ScopeDynamic Scope
DefinitionScope is determined at the time of function declarationScope is determined at the time of function execution
Where Used?JavaScript, PythonSome old languages like Bash, Perl
How Variables are Resolved?By looking at the source code structureBy following the call stack

Since JavaScript uses lexical scoping, functions always have access to variables in the scope where they were defined, not where they are called.

How Lexical Scope Works

Lexical scope means a function remembers the environment (variables) where it was created.

Variable Lookup in JavaScript

Whenever a function accesses a variable, JavaScript follows this lookup order:

  1. Local Scope – First, the function checks its own variables.
  2. Enclosing Scope – If the variable isn’t found locally, JavaScript looks into the outer (parent) scope.
  3. Global Scope – If it’s still not found, JavaScript checks the global scope.
  4. Reference Error – If the variable isn’t found anywhere, JavaScript throws a ReferenceError.

Example: Lexical Scope in Action

function outer() {
    let outerVar = "I'm in outer!";
    
    function inner() {
        console.log(outerVar);  // Accessible due to lexical scoping
    }
    
    inner();
}
outer();
  • Output: "I'm in outer!"
  • Here, inner() has access to outerVar because of lexical scope.

Closures and Their Relationship with Lexical Scope

A closure is a function that remembers variables from its lexical scope even after execution.

Key Differences Between Lexical Scope and Closures

FeatureLexical ScopeClosures
What it does?Defines where variables are accessibleAllows functions to retain access to outer variables
When is it used?At function declarationWhen a function is returned and executed later
ExampleVariable lookup inside a functionA function “remembering” a variable

Example: Closures Retaining Lexical Scope

function counter() {
    let count = 0;  // Lexical Scope

    return function() {
        count++;  // Closure retains access
        console.log(count);
    };
}

const increment = counter();
increment(); // Output: 1
increment(); // Output: 2

Here, even after counter() finishes execution, count persists because the inner function creates a closure.

Real-World Examples of Closures in Action

Creating Private Variables (Encapsulation)

function createUser(name) {
    let password = "secret123";  // Private variable

    return {
        getName: function() {
            return name;
        },
        checkPassword: function(pass) {
            return pass === password;
        }
    };
}

const user = createUser("Alice");
console.log(user.getName());        // "Alice"
console.log(user.checkPassword("123")); // false
console.log(user.checkPassword("secret123")); // true

Event Listeners Retaining Data

function setupClickHandler(buttonId) {
    let count = 0;

    document.getElementById(buttonId).addEventListener("click", function() {
        count++;
        console.log(`Button clicked ${count} times`);
    });
}

setupClickHandler("myButton");
  • The event listener retains access to count, even though setupClickHandler has already executed.

Best Practices for Working with Scope and Closures

Minimize Global Variables

// ❌ Bad practice
var globalCount = 0;

// ✅ Good practice
function increment() {
    let count = 0;
    return function() { count++; };
}

Use let and const Instead of var

function testScope() {
    if (true) {
        let localVar = "I'm safe!";
    }
    console.log(localVar);  // ❌ ReferenceError
}

Clear Event Listeners

const btn = document.getElementById("myBtn");
function handleClick() {
    console.log("Clicked!");
}
btn.addEventListener("click", handleClick);

// ✅ Remove listener when done
btn.removeEventListener("click", handleClick);

FAQs

What is lexical scope in JavaScript?

  • Lexical scope means a function’s variables are determined by where the function is defined, not where it’s called.

How do closures work?

  • Closures allow functions to “remember” variables from their lexical scope, even after execution.

Are lexical scope and closures the same thing?

  • No. Lexical scope determines variable access, while closures “retain” variables from lexical scope even after execution.

How do I prevent closures from causing memory leaks?

  • Remove event listeners when not needed.
  • Use weak references (WeakMap).
  • Avoid unnecessary variable retention.

Metana Guarantees a Job 💼

Plus Risk Free 2-Week Refund Policy ✨

You’re guaranteed a new job in web3—or you’ll get a full tuition refund. We also offer a hassle-free two-week refund policy. If you’re not satisfied with your purchase for any reason, you can request a refund, no questions asked.

Web3 Solidity Bootcamp

The most advanced Solidity curriculum on the internet!

Full Stack Web3 Beginner Bootcamp

Learn foundational principles while gaining hands-on experience with Ethereum, DeFi, and Solidity.

You may also like

Metana Guarantees a Job 💼

Plus Risk Free 2-Week Refund Policy

You’re guaranteed a new job in web3—or you’ll get a full tuition refund. We also offer a hassle-free two-week refund policy. If you're not satisfied with your purchase for any reason, you can request a refund, no questions asked.

Web3 Solidity Bootcamp

The most advanced Solidity curriculum on the internet

Full Stack Web3 Beginner Bootcamp

Learn foundational principles while gaining hands-on experience with Ethereum, DeFi, and Solidity.

Learn foundational principles while gaining hands-on experience with Ethereum, DeFi, and Solidity.

Events by Metana

Dive into the exciting world of Web3 with us as we explore cutting-edge technical topics, provide valuable insights into the job market landscape, and offer guidance on securing lucrative positions in Web3.

Subscribe to Lettercamp

We help you land your dream job! Subscribe to find out how

Spring Career Kickstart Book a call before Mar 10th to get 20% OFF!

20% oFF

Days
Hours
Minutes
Seconds

New Application Alert!

A user just applied for Metana Web3 Solidity Bootcamp. Start your application here : metana.io/apply

Get a detailed look at our Full Stack Bootcamp

Understand the goal of the bootcamp

Find out more about the course

Explore our methodology & what technologies we teach

You are downloading 2025 updated Full stack Bootcamp syllabus!

Download the syllabus to discover our Full-Stack Software Engineering Bootcamp curriculum, including key modules, project-based learning details, skill outcomes, and career support. Get a clear path to becoming a top developer.

Software Engineering Syllabus Download

"*" indicates required fields

This field is for validation purposes and should be left unchanged.