Scope and The Scope Chain

Understanding Scopes in Javascript

January 25, 2023

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:

  1. Global scope
  2. Function scope
  3. 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.

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.

Scope Chain

  • First, we start with the Global scope. There we only have the fullName variable. There’s a userInfo 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 an age and isWorking variables. Also, inside the userInfo function, we have access to the global variable fullName.
  • Next, we have an if block inside the userInfo function which has two variables declared: text and isWorking. Here the text variable is block scoped because it is declared with let. But the isWorking variable will be a part of the userInfo function scope because it is declared with var. As we mentioned earlier, variables declared with var are not block-scoped. Since it’s part of the userInfo scope, now the displayJob function also has access to it.
  • Inside the userInfo function, we have a displayJob function which also creates its own scope. It contains the job 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!


Engineering Goodies

Zaur Ibrahimov
Personal blog by Zaur IbrahimovThings that interest me