Yandex

JavaScript Lexical Scope
Scope Chain, Function Nesting, and Closures



What is Lexical Scope in JavaScript?

In JavaScript, lexical scope (also called static scope) means that the accessibility of variables is determined by the position of functions and blocks in the source code — not at runtime, but when the code is written. In simpler terms, inner functions have access to variables defined in their outer (parent) scopes.

Understanding Lexical Scope with a Basic Example


function outerFunction() {
    let outerVariable = "I'm from the outer function";

    function innerFunction() {
        console.log(outerVariable);
    }

    innerFunction();
}

outerFunction();
I'm from the outer function

Explanation:

Here, innerFunction is defined inside outerFunction, so it has access to outerVariable due to lexical scoping. JavaScript knows this during the time of writing the code, not at runtime.

Scope Chain: How JavaScript Finds Variables

When a variable is accessed, JavaScript looks for it in the current scope. If it's not found, it walks up the scope chain — all the way to the global scope if necessary.


let globalVar = "Global";

function levelOne() {
    let levelOneVar = "Level 1";

    function levelTwo() {
        let levelTwoVar = "Level 2";

        console.log(globalVar);     // Accessible
        console.log(levelOneVar);   // Accessible
        console.log(levelTwoVar);   // Accessible
    }

    levelTwo();
}

levelOne();
Global
Level 1
Level 2

But It Doesn’t Work in Reverse


function outer() {
    let outerVar = "outer";

    function inner() {
        let innerVar = "inner";
        console.log(outerVar); // Works
    }

    inner();
    console.log(innerVar); // ❌ Error: innerVar is not defined
}

outer();
outer
Uncaught ReferenceError: innerVar is not defined

Variables Are Not Shared Across Siblings

Lexical scope only applies to nested relationships, not sibling functions.


function one() {
    let msg = "from one";
}

function two() {
    console.log(msg); // ❌ Error
}

one();
two();
Uncaught ReferenceError: msg is not defined

Nested Functions and Lexical Environment

Each function creates its own lexical environment. Inner functions carry a reference to their parent's scope. Let's visualize that:


function grandParent() {
    let gp = "grandparent";

    function parent() {
        let p = "parent";

        function child() {
            console.log(gp); // ✅
            console.log(p);  // ✅
        }

        child();
    }

    parent();
}

grandParent();
grandparent
parent

Real-Life Scenario: User Authentication Flow


function authenticate(username) {
    let secret = "token_" + username;

    function getToken() {
        return secret;
    }

    return getToken;
}

const tokenFetcher = authenticate("JohnDoe");
console.log(tokenFetcher()); // Lexical scope retains 'secret'
token_JohnDoe

Closures Are a Direct Result of Lexical Scope

A closure happens when a function "remembers" its lexical scope even after the outer function has finished executing.


function counter() {
    let count = 0;

    return function () {
        count++;
        console.log(count);
    };
}

const increment = counter();
increment(); // 1
increment(); // 2
increment(); // 3
1
2
3

Why Lexical Scope Matters

  • Helps with code modularity and predictability.
  • Provides the foundation for closures and callback functions.
  • Improves memory efficiency when managing state in functions.

Common Mistakes to Avoid

  • Thinking variables are dynamically scoped (they’re not).
  • Expecting sibling functions to access each other’s scope.
  • Misunderstanding how closures keep references, not copies, of variables.

Conclusion

Lexical scope is a core concept that gives JavaScript its power and flexibility. Mastering it lays the foundation for understanding closures, module patterns, and advanced concepts like currying and memoization. Always remember — where you write your functions matters just as much as how you write them.



Welcome to ProgramGuru

Sign up to start your journey with us

Support ProgramGuru.org

You can support this website with a contribution of your choice.

When making a contribution, mention your name, and programguru.org in the message. Your name shall be displayed in the sponsors list.

PayPal

UPI

PhonePe QR

MALLIKARJUNA M