Introduction
To become proficient in JavaScript Engineering, it is essential to understand the concept scope chain. The scope chain is a fundamental concept that determines how variables are accessed and resolved within a JavaScript program. In this article, we will delve into the scope chain in JavaScript, explore its importance, and provide examples to help you grasp the concept.
What is Scope?
The scope in JavaScript is closely tied to its lexical environment.
Let's understand the above definition by example:
function one() {
var a = 100
two();
function two(){
console.log(a)
}
}
one()
In the example provided, what should you anticipate as the output? Will it be 100, undefined, or perhaps something different?
The correct answer is 100. Let's delve into why it produces an output of 100. Once you grasp this, you'll gain a deeper understanding of the scope chain.
Let's first understand the execution context diagram of the above code :
In the diagram above, we start with the global execution context. Within this context, global variables and functions are initialized. In this specific case, we have a global function named "one
," which is stored in the memory of the global execution context. Notably, you'll notice a blue box at the bottom of the memory, representing the lexical environment of the global execution context, which is null
. This concept will become clearer as we explore subsequent execution contexts.
Next, when the "one
" function is invoked, a new execution context is created, visible as the "Call stack one" in the diagram. Within this context, variables are initially assigned as undefined
, and then they receive their values. In this example, the variable "a
" is assigned the value 100, and "two
" is assigned as a function reference. Once again, there is a blue box at the bottom of this execution context, signifying the lexical environment of the parent context. In this case, the lexical environment of "Call stack one" points back to the global execution context because that is its parent context.
Subsequently, when the "two
" function is invoked, yet another execution context is created. While there are no variables in this context, the blue box at the bottom still indicates a reference to the lexical environment of the parent context, which, in this case, is "function one
." This connection reinforces the link between "function two
" and its parent context, "function one
."
Practical understanding
Now that you have understood what is lexical environment, let's understand how the previous worked internally.
function one() {
var a = 100
two();
function two(){
console.log(a)
}
}
one()
When JavaScript encounters the line console.log(a)
, it attempts to locate the variable a
within the scope of the two
function. However, it doesn't find the variable there. In this situation, it proceeds to search within the lexical environment of two
. As illustrated in the execution context diagram above, the lexical environment of the execution context two
is connected to the scope of one
. Consequently, it continues its search for the variable a
within the scope of two
, ultimately finding it within the scope of one
. As a result, it logs the value 100 to the console.
If a
would have not defined inside function one, can you guess what would have happened? You are right, javascript would again look for variable a
on lexical environment of function one that is on global execution context. Again if it didn't found it over global execution context then it would have searched over lexical environment of the global execution context that is null. Then you will get an error that b is not defined.
Conclusion
Now that we've grasped the entire code, let's draw our conclusion: The process of locating variables is called the "scope chain." This means first searching for the variable within the immediate local scope of a function, and if it's not found there, then exploring the outer lexical environments. In simple terms, we refer to this entire process as the "scope chain."