Have you ever heard the term “lexical environment” in JavaScript and wondered what it really means? Perhaps you’ve come across related phrases such as “lexical scope” or “lexical analysis” and found them confusing. In this article, we’ll simplify the concept of lexical environments and explore how they work in JavaScript.
At its core, a lexical environment refers to where code is written. When the JavaScript engine reads through our code, it pays attention to the location of each piece of code. Each time we create an execution context, a “little universe” or lexical environment gets created. This is where the engine looks to determine what actions to take and what functions have access to certain information.
To illustrate this, let’s look at an example. Consider the code below:
function sayMyName() {
function findMyName() {
function printName() {
console.log(myName);
}
var myName = "John";
printName();
}
findMyName();
}
sayMyName();
In this code, we have multiple lexical environments. The sayMyName
function creates a new universe, where it defines the findMyName
function. The findMyName
function, in turn, creates a new universe where it defines the printName
function and declares a variable myName
.
Since printName
is defined within the findMyName
function, it has access to the myName
variable within that same lexical environment. But if we were to define a new function within printName
, that function would belong to yet another lexical environment and would not have access to the myName
variable.
It’s important to note that lexical environments are created at compile time, not runtime. This means that the location of code is determined before the code is actually executed. So, if we were to call the window.printName
function, it would work because the printName
function is defined within the global lexical environment.
In conclusion, the concept of lexical environments is fundamental to understanding how JavaScript works. Every time we create a new function, we create a new universe, or lexical environment, where we can define new variables and functions. By understanding the relationship between lexical environments and execution contexts, we can write better code and avoid common errors.