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
- 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
outerVaris declared inouterFunctionand is accessible withinouterFunctionand any nested functions likeinnerFunction, due to lexical scoping.innerVaris declared ininnerFunctionand is only accessible withininnerFunction.
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: 3Explanation of Closures
makeCounterdefines a local variablecountand a functionincrementCounterthat modifiescount.incrementCounterforms a closure that includes the variablecountfrommakeCounter.counteris a reference to theincrementCounterfunction, and each time it’s called, it maintains access to thecountvariable 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.

