Before we get started what you need is the basic understanding of how Functions and Variable Environment work together in JavaScript.
If you do not know them, no worries. I've already written a blog about them.
OK then. Let's get started.
We have a small piece of code with us here.
function a() {
function c() {
console.log(b);
}
c();
}
var b = 21;
a();
Inside function c( ) we are trying to access variable b. Now let's run this program.
We could access variable b inside function c( ) which is again inside another function a( ). For now everything is good.
Now let's just try accessing the same variable but this time in the global scope like below.
function a() {
var b = 21;
function c() {}
c();
}
console.log(b);
a();
We would run into an error that said variable b is not defined at all.
This is where we need the concept of scope.
Scope in simple words mean where all you could access variables, functions and objects in a code.
When we run the above program we will have a call stack like below.
We have a global execution context that is pushed to call stack first. Then for each function invoked we have a separate execution context for the function a( ) and c( ) as well.
Now let's understand what Lexical Environment is.
Whenever an execution context is created a lexical environment is also created.
Lexical Environment = Local Memory + Lexical Environment of its Parent
For lexical in coding terms, we can say that function c( ) is lexically inside function a( ). Also for function a( ), it is lexically inside global scope.
Now follow along with what I say with the diagram above. Each memory phase of each execution context has a reference to the lexical environment of its parent.
function a() {
var b = 21;
function c() {
console.log(b);
}
c();
}
a();
For the above code the lexical environment of function c( ) is its local memory with the lexical environment of its parent which is function a( ).
The lexical environment of function a( ) is its local memory with the lexical environment of its parent which is the global scope.
The lexical environment of global scope is its local memory with the lexical environment of its parent which is the null. Meaning its reference points to nothing.
Now let us try to console log variable b inside function c( ).
function a() {
var b = 21;
function c() {
console.log(b);
}
c();
}
a();
In line 4 JavaScript looks for variable b in the local memory of function c( ). When it doesn't find it, it simply uses the reference to the lexical environment of its parent which is function a( ). In local memory of function a( ), it finds out variable b and goes back to its original execution context and console logs variable b.
Suppose the JavaScript engine never found out variable b in the local memory of function a( ). It would simply use the reference of the lexical environment of function a( ) parent that is the global execution context. Now again if variable b was never found then it would use the reference of the lexical environment of its parent too.
For the global execution context, the lexical environment of its parent is simply "null". This is where the program ends and the JS engine would simply say variable b is not defined at all.
This mechanism of searching for the variable from its present local memory all the way to the lexical environment of global execution context if needed is what we call SCOPE CHAIN.
Were you not blown away?
Haha!!! I know this was just amazing all together.
If you made it this far then congrats you just learned ->
- What scope is.
- What scope chain is.
- What lexical environment is.
If you learned anything from this blog then please leave a like and comment on what you felt about the blog.