In my previous article about How Javascript Works Behind The Scenes, I talked about the creation phase of an Execution Context. There we have seen it happen in 3 stages and the second one is the Creation of the Scope Chain. In this article, we will go through the scope and the scope chain in order to get an understanding of these tricky concepts. They’re one of the fundamental concepts in Javascript and are very important to learn.
Let’s begin!
Scope
Scope refers to a space or environment in which variables or functions are declared. Scoping in Javascript controls how our program’s variables are organized and accessed. In other words, it basically helps us to determine what variables or functions we can or cannot access.
There are 3 types of scope in Javascript:
- Global scope
- Function scope
- Block scope
Global Scope
Variables declared outside of any function or code blocks have Global Scope. The variables in Global Scope can be accessed from anywhere in a Javascript program. For instance:
const greeting = “Hello”;
function greet() {
console.log(greeting);
}
greet(); // logs Hello
Here we declared the greeting
variable outside of the greet
function and we’re able to access it inside there.
Function Scope
Each function creates its own scope. The variables declared inside a function are only accessible inside that function and any of its nested functions. Function Scope is also called Local Scope.
function greet() {
var greeting = “Hello”
console.log(greeting); // logs Hello
}
greet(); // logs Hello
console.log(greeting); // ReferenceError: greeting is not defined
Here we declared the greeting
variable inside the greet
function and it’s now only accessible inside that function (or any other nested functions inside of it). When we try to access it outside, we get a ReferenceError
.
Block Scope
Before ES6 (2015), Javascript had only Global Scope and Function Scope.
ES6 introduced let
and const
keywords and by using them, blocks also can create scopes. In other words, everything that’s between curly braces {}
.
function calcAge() {
var age = 20;
if (age > 18) {
let text = "Adult";
console.log(text); // logs Adult
}
console.log(text); // ReferenceError: text is not defined
}
calcAge();
As you can see above, text
is a block scope variable and can only be accessed inside the respective if
blocks.
let
and const
declarations, but not var
declarations.
Scope Chain
The Scope Chain is the hierarchy of scopes that will be looked up to find a variable or a function. In other words, this is how Javascript looks for variables. The Scope Chain is created after the Variable Object in the creation of an Execution Context.
In order to understand it better, let’s have a look at this code below and walk through the process step by step.
-
First, we start with the Global scope. There we only have the
fullName
variable. There’s auserInfo
function declared in the global scope as well. But in order to keep things simple, we’re going to focus on the variables. Also, keep in mind that functions and variables work the same way in the scope chain. -
If you remember, each function creates its own scope. So inside the Global scope, we have scope for
userInfo
function. Inside this function, we have anage
andisWorking
variables. Also, inside theuserInfo
function, we have access to the global variablefullName
. -
Next, we have an
if
block inside theuserInfo
function which has two variables declared:text
andisWorking
. Here thetext
variable is block scoped because it is declared withlet
. But theisWorking
variable will be a part of theuserInfo
function scope because it is declared withvar
. As we mentioned earlier, variables declared withvar
are not block-scoped. Since it’s part of theuserInfo
scope, now thedisplayJob
function also has access to it. -
Inside the
userInfo
function, we have adisplayJob
function which also creates its own scope. It contains thejob
variable. As you can see here, now we have a nested structure of scopes with one scope inside the other.
As you can see in the above example, displayJob
function logs the result by using fullName
and age
variables.
But those variables are not inside the function. How do we access them?
Well, in this case, Javascript looks inside the displayJob
function to see if the variable is declared there.
When Javascript can’t find it there, it will reach out to the outer scope.
It will look up in the scope chain until it finds the variables. This process is called Variable Lookup.
And that’s it. I hope it will be helpful for many people. Next time we’re going to talk about another interesting topic: Temporal Dead Zone (TDZ) and Hoisting.
Thanks for reading!