Scope and scope chain are some fundamental concepts of JavaScript , which helps us understand how JavaScript works. Learning about these concepts can improve our debugging skills.
Scope
Scope refers to a space or an area in which a particular variable is accessible. There are three types of scope in JS:
- Global scope
- Function scope
- Block scope
Global scope: Variables which our declared outside any function are in the global scope. That means we can access these variables anywhere inside our program.
Example:
var name="Atishay"
function printName(){
console.log(name)
}
printName();//Atishay
Here we can see that name is declared outside function printName() but the function can still access this variable. This is global scope.
Local scope: Variables that our declared inside a function have local scope. That means we can access these variables only inside the function in which they are declared.
Example:
function printName(){
var name='Atishay';
console.log(name);
}
printName(); // Atishay
console.log(name); // error
In this example as the variable name is declared inside the function printName(), we cannot access it outside the function.
Block scope: With the introduction of let and const in ES6, we can use block scope in JavaScript. If we declare variables with let and const inside curly braces, we can use these variables only inside those curly braces. Generally we use this in for loop, if statements.
Example:
var x=true;
if(x){
let name='Atishay';
console.log(name); //Atishay
}
console.log(name); // error
Here we can see that we cannot access the variable name outside the if statement because it is declared with let inside the statement.
Note:- Variables declared with var are function scoped and variables declared with let and const are block scoped. So basically if we declare variables with var in if statements or for loops then we can still access these variables outside the curly braces in which they are defined.
Scope chain
Before understanding scope chain, we have to understand what is a lexical environment. With each execution context , a lexical environment is created, A lexical environment is basically the local scope of the function with also a reference to its lexical parent's environment.
Here the term lexical refers to the space in which a particular piece of code is physically present. We will understand this better while discussing some examples . Now what is scope chain? scope chain is basically an order which JS engine follows to access different variables according to our needs.
Now let us discuss some important examples to understand this better:
Example 1: Here we can say that printName() lexically sits inside firstName().
function firstName(){
var name='Atishay';
function printName(){
console.log(name);
}
printName();
}
firstName();
Here is what happens in this program:
- Global execution context is created
- firstName function execution context is stacked over GEC and then it is executed.
- printName function execution context is stacked over firstName function context.
- when printName function is executed line by line , due to the console.log(name) statement, JS engine searches the value of name in its local scope when it is unable to identify the value assigned to the name variable in local scope , it checks for the value in printName function's lexical parent environment.
- printName function's lexical parent is the firstName function because printName function is physically sitting inside the firstName function.
- Here it finds the value of name to be 'Atishay'.
- Then the value is printed in the console.
Let's discuss a tricky example now:
Example 2:
function printName(){
console.log(name)
}
function firstName(){
var name='Atishay';
printName();
}
firstName();
Here what do you think the output will be? will it be 'Atishay?'
The answer is that the js engine will throw an error.
Let's think about this code logically:
- when printName is invoked inside the firstName function, JS engine searches the value of name in its local scope.
- As name is not defined inside printName function, where will JS engine search for the value of name?
- It will search it in the lexical environment of printName function's lexical parent.
- lexical parent of printName function is not the firstName function , lexical parent of printName function is the main program(because printName is physically sitting inside the main program), that means it will search the value of name in the global scope.
- As there is no name variable declared in the global scope, the JS engine will throw a reference error.
This chain which JS engine follows in order get the value of different variables is called scope chain. The chain gets exhausted at the global scope.
That's it from my side! I hope that now you have little better understanding of scope and scope chain in Javascript.
Thank you!