Scope Chain is process of looking for the variable at own local memory of the function. If do not find it in the local memory of that function then it checks its lexical parent and again checks the local memory of its lexical parent and keep doing this until it finds that variable. Scope chain works in one way only.
It may be little difficult to understand the scope chain by above definition. So let’s understand it by using some examples.
Scope Chain Examples
var productName = "Mobile"; function displayProductName() { console.log(productName); } displayProductName(); Output: Mobile
This is the simple example. We have the global variable name productName and we also have a global function name as displayProductName() which simply logs the product name in console. And we are calling the function below. And most of you will know what should be the output. It should print “Mobile” in console.
There is nothing any surprise in output. So you can see displayProductName() function does not have its own local variable productName. Means we have not declared productName inside displayProductName(). It’s outside the displayProductName(). So actually this displayProductName() is having access to productName property. How does it actually go and search that there has to be a productName outside of it.
Before we move on to the explanation , we will take one more example.
var productName = "Mobile"; function displayProductName() { console.log(productName); var productPrice = 5000; function displayProductPrice() { console.log(productPrice); } displayProductPrice(); } displayProductName(); Output: Mobile 5000
We have taken the previous example but here we have some extra line of code. We have created another variable productPrice and another function i.e displayProductPrice() inside displayProductName() function. And called displayProductPrice() function. This time we are printing productPrice in console. So when we will run this code it will simply print productPrice as 5000.
Here also you can see displayProductPrice does not have its local variable productPrice but displayProductName() does.
Now let’s do the small change in the code –
var productName = "Mobile"; var productPrice = 5000; function displayProductName() { console.log(productName); function displayProductPrice() { console.log(productPrice); } displayProductPrice(); } displayProductName(); Output: Mobile 5000
This time we simply moved the productPrice variable into top and outside the displayProductName(). Now we will run the code it will again give the same output. So how displayProductPrice() knows that where it should pick productPrice because it does not have productPrice variable inside it. And heres the scope chain comes into the picture.
But before moving to scope chain lets understand whats the particular function having access to. For that we need to understand the meaning of the world lexical. Lexical means where exactly in the code something written. So in the example displayProductPrice() is written inside the displayProductName. It does not matter where we are calling displayProductPrice(). So the word lexical is more related to where we have actually define the function. So displayProductPrice() is defined inside the displayProductName().
Now comes the word lexical parent. Lexical parent of any function is simply where is it written. In our case lexical parent of displayProductPrice() is displayProductName(). Now we need to understand lexical environment. So lexical environment is combination of two things. Local memory along with its parents lexical environment.
For example if displayProductPrice() will have its own productPrice variable. Then it would be a local memory of displayProductPrice(). Whatever we write inside the displayProductPrice() will be the local memory of the displayProductPrice(). With combination with its parent lexical environment is the lexical environment for displayProductPrice().
Let’s again do some small change in our code –
var productName = "Mobile"; function displayProductName() { var productPrice = 5000; console.log(productName); function displayProductPrice() { console.log(productPrice); } displayProductPrice(); } displayProductName(); Output: Mobile 5000
Now again we have moved the productPrice variable inside the displayProductName(). So when we will try to do console.log productPrice so it will first look its local memory if the productPrice is available inside it. If not then it will go to its parent lexical environment. So inside the parent lexical environment means inside displayProductName() productPrice is declared. Hence displayProductPrice() will be able to print productPrice value.
In case if productPrice will be not there in displayProductName() instead it will be outside of it then it will look outside of the displayProductName(). And it will pick the value from there that is our global execution context right now. If productPrice will not declare globally as well then it will give the reference error that productPrice is not defined. When we reached the top most level in that case there is no any lexical parent so it will be null.
Now if you will again read the definition given above in the first line , you will be able to understand what actually the scope chain and how it works.