JavaScript lexical environment is a data structure that holds an identifier-variable mapping. Where identifier refers to the name of variables/functions, and variable is the reference to the actual object. It also holds a reference to a parent lexical environment.
Lexical Environment: Local Memory + Lexical Environment of its Parent
Lexical in general means in a hierarchy or in a sequence. Whenever a new execution context(EC) is created a new lexical environment is created and it is referenced in the local EC in memory space.
The lexical environment in JavaScript
Simple example code variables and functions are live or physically present during the program execution.
<!DOCTYPE html>
<html>
<body>
<script>
// This is what a lexical environment conceptually look like:
//LexicalEnvironment = {
//Identifier: <value>,
//Identifier: <function object>
//}
function a() {
var b = 10;
c();
function c() {
console.log(b); //it prints the right value.
}
}
a();
console.log(b); // prints NOT DEFINED!
</script>
</body>
</html>
Output:
function c is lexically inside function a.
- So in EC of c(), variables and fun in c (none) + reference of lexical env of parent a() is there
- LE of a() in turn is its memory space + reference to LE of parent (Global EC)
- LE of Global EC points to its memory space + NULL (as no parent for Global EC).
Source: https://www.intervue.io/developer
Each time a function is invoked, a new lexical environment is created. This environment consists of two main components:
- Environment Record: This component stores all local variables as well as the function declaration within the scope of the function. There are two types of environment records: declarative environment record (for variables declared using
let
,const
, andclass
) and object environment record (for variables declared usingvar
). - Reference to the Outer Environment: This is a reference to the lexical environment in which the current function was defined. This allows functions to access variables from their containing scopes, forming a chain of nested lexical environments known as the scope chain.
When a function is executed, JavaScript looks up the scope chain to resolve variable names. If a variable is not found in the current lexical environment, it looks in the outer lexical environment until it reaches the global lexical environment.
Here’s a simple example to illustrate lexical environments:
function outerFunction() {
var outerVar = 'I am from outer function';
function innerFunction() {
var innerVar = 'I am from inner function';
console.log(innerVar); // Accessible, as it's declared in the same lexical environment
console.log(outerVar); // Accessible, as it's in the outer lexical environment
}
innerFunction();
}
outerFunction();
In this example, innerFunction
has access to both innerVar
and outerVar
because they are within its lexical scope.
How does JavaScript’s lexical environment maintain variable declarations within nested block scopes?
Answer: The block statement creates a new lexical environment.
A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based on the lexical nesting structure of ECMAScript code. A Lexical Environment consists of an Environment Record and a possibly null reference to an outer Lexical Environment. Usually, a Lexical Environment is associated with some specific syntactic structure of ECMAScript code such as a function declaration, a BlockStatement, or a Catch clause of a try statement, and a new Lexical Environment is created each time such code is evaluated.
Source: stackoverflow.com
Do comment if you have any doubts or suggestions on this Js Advanced topic.
Note: The All JS Examples codes are tested on the Firefox browser and the Chrome browser.
OS: Windows 10
Code: HTML 5 Version