Scope in Javascript
Scope determines the accessibility of variables in JavaScript. It means where you can access a particular variable in your code. In Javascript, we have 2 types of scope:
- Global Scope
- Local Scope
Global Scope
Whenever you declare a variable outside of any function, then it is in the global scope and the variable is called global variable. Global variables can be accessed from anywhere in the code.
Example:
var x = 10;
Local Scope
Whenever you declare a variable inside of a function, then it is in the local scope and the variable is called local variable. Local variables can only be accessed inside of the function they are declared in.
Example:
function localScope() {
var x = 10;
}
localScope();
But how does javascript allow global variables to be accessed from anywhere and restrict local variables from getting access outside of the function they are declared in? It happens because of Lexical Environment.
What is Lexical Environment?
A lexical environment consists of 2 things:
- Local Memory Space
- A reference to the Lexical Environment of parent
Local Memory Space means the memory space (where variables are stored) of a function or global scope if you are outside of any function. Reference means it has access to the lexical environment of the parent.
Let's understand it with some simple examples.
Example 1
var x = 10;
function printX() {
console.log(x);
}
printX();
// Output
10
Here, we created a variable x and assigned 10 to it then we are calling a function that prints the value of x. Now, when we call the function it outputs 10 but we don't actually have x inside the function, we have it in the global scope. How does it access x from the global scope?
The answer is simple, it's because of the lexical environment.
When we try to print x inside of the function, the javascript engine tries to find it in the lexical environment of the function which consists of local memory and a reference to the lexical environment of the parent. When it fails to find it in the local memory of function then it will move to the lexical environment of the parent (global scope in this case) using the reference. Which again consists of local memory and a reference to the lexical environment of its parent. The engine will find x in the memory of the global scope and will print it.
Example 2
function createX() {
var x = 10;
}
createX();
console.log(x);
Uncaught ReferenceError: x is not defined
We get an error, but why?
When we try to access x in the global scope, the javascript engine tries to find it in the lexical environment. X is not defined in the memory space of global scope (it is actually in the local memory space of createX). So it moves to the lexical environment of its parent. We don't have any parent of global scope, so it means x does not exist. That's why we get that error.
Example 3
var x = 10;
function outer() {
function inner() {
console.log(x);
}
inner();
}
outer();
// Output
10
Here we have an outer function and then an inner function inside of it which tries to access x. When we call inner, the javascript engine tries to find x in its lexical environment. It fails to find it in the local memory space of inner, so using the reference to the lexical environment of the parent, it moves to the lexical environment of outer, still, x is not in the local memory space of outer, again using the reference, the engine moves to the lexical environment of its parent (global scope). And there we have x in the memory. So it prints the value x in the console.
Scope Chain
The way Javascript Engine moves from one lexical environment to another to find the variable is called scope chain.
Top comments (0)