Progressive Full Stack Application Development with Live Projects

Lexical Scope in JavaScript
JavaScript Lesson

Lexical Scope in JavaScript

Lexical scope (also known as static scope) is a type of scope in which the scope of variables is determined by their location in the source code, as opposed to the context in which a function is executed. In simpler terms, it means that a function’s scope is determined at the time the function is defined, not when it’s called

Key Points About Lexical Scope

  1. Scope is Defined at Declaration Time: In lexical scope, the scope of variables is fixed at the time of function declaration. This means that functions have access to variables in the scopes where they are defined, not where they are called.

2. Nested Functions Have Access to Outer Functions: Functions defined within other functions have access to variables in the outer function’s scope due to lexical scoping. This is known as a closure.

3. Scope Chain is Static: The scope chain is determined based on where functions and variables are declared, not where they are executed.

Example of Lexical Scope

Consider the following example to illustrate lexical scope:

function outerFunction() {
    let outerVar = 'I am an outer variable';
    
    function innerFunction() {
        let innerVar = 'I am an inner variable';
        console.log(outerVar); // Logs: 'I am an outer variable'
        console.log(innerVar); // Logs: 'I am an inner variable'
    }
    
    innerFunction();
}

outerFunction();

Explanation

  • outerVar is declared in outerFunction and is accessible within outerFunction and any nested functions like innerFunction, due to lexical scoping.
  • innerVar is declared in innerFunction and is only accessible within innerFunction.

Even though innerFunction is called within outerFunction, the access to outerVar is determined by the scope in which innerFunction was defined (i.e., within outerFunction), not where innerFunction is invoked.

Closures

Lexical scoping leads to the concept of closures, which are functions that capture their lexical environment. Here’s an example demonstrating closures:

function makeCounter() {
    let count = 0; // `count` is in the lexical scope of `incrementCounter`
    
    function incrementCounter() {
        count += 1;
        return count;
    }
    
    return incrementCounter;
}

const counter = makeCounter();
console.log(counter()); // Logs: 1
console.log(counter()); // Logs: 2
console.log(counter()); // Logs: 3

Explanation of Closures

  • makeCounter defines a local variable count and a function incrementCounter that modifies count.
  • incrementCounter forms a closure that includes the variable count from makeCounter.
  • counter is a reference to the incrementCounter function, and each time it’s called, it maintains access to the count variable from its lexical environment.

In summary, lexical scope ensures that functions retain access to variables from the scope in which they were defined, creating powerful patterns like closures that allow functions to remember and manipulate their own environment.

Leave a Reply