Lexical Environment: A must read before Closures
In JavaScript, you must have heard of the term Lexical Environment several times.
So what is this Lexical Environment ?
“Lexical Environment” is basically a specification object, which stores the association of identifiers to their functions and variables.
Every variable, function, and code block has its own Lexical Environment.
Consider Lexical environment into two parts:
1. Environment: This stores all the local variables and value of this.
2. Reference: A reference to the outer environment in which it was created.
Let’s study them further for variables and functions in more detail.
Case A: Variable
In the image below, the comments explain the Lexical Environment.
- When the script starts running the global Lexical Environment is pre-populated with the variables declared inside it but all of them are uninitialised and reference to the outer environment for all the variables is null.
- When it hits the line
let newVariable ;
we can use this variable to initialise it with some value as it is nowundefined
. - Now we assigned
newVariable = "Hello";
and the Lexical Environment also gets updated. - Then, we change the value as
newVariable = "Hello";
again the Lexical Environment gets updated.
Case B: Function
Functions became available to use even before their declarations, as they are immediately initialised when the script runs.
When a function runs, a Lexical Environment is created to store its local variables with their values and the Reference to the outer environment in which it was created.
Functions first searches for the variable inside their inner Lexical Environment, if not found they move to outer one and so on until the global one.
Here, the function eat
has variable fruit
inside its Lexical Environment, but count
is not found inside its Lexical Environment, so it makes use of the Reference to the outer Lexical Environment to search for count
and eventually found it. Therefore, the output is 2 apple
.
Note: With Function expression syntax, functions are not instantly initialised and can’t be used until the script hit “let
” keyword for them.let eat = function(fruit){console.log(`Eat ${fruit}!`);}