Skip to main content

Command Palette

Search for a command to run...

Understanding Execution Context in Javascript

Updated
5 min read

Hello folks! Hope you are doing good🙂. Let me guess, you are probably here to know about the code execution process carried out by JS engine.

This blog assumes that you are aware with some basics of javascript and a little bit about chrome dev debugger tool.

Takeaways after reading this blog:

  1. You will understand how JS engine executes the code under the hood by creating an execution context.
  2. You will be able to write better code as you know how the language works.

Before deep diving into execution context let me tell you that everything in JS happens(memory allocation and code execution) inside Execution Context.

What Exactly is this Execution Context?

Execution Context can be defined as an environment container which consists of two components namely Variable Environment(memory) and Thread of Execution(Code).

Memory is the place where variables and functions are stored in key-value pair form and in code component code is been executed.

There are two types of execution context:

  • Global execution context(GEC)
  • Function execution context(FEC)

We will use this execution context GEC and FEC as short-code for whole blog. And each of these has 2 phases which are memory creation phase and code execution phase

What happens when code runs?

Let us consider a code snippet over here

var a1 = 5;
var a2 = 10;

function add(a, b) {
  var sum = a + b;
  return sum;
}

var sumOfNumbers = add(a1, a2);
console.log(sumOfNumbers);

Above is a code of normal addition.

Whenever we run code , a Global Execution Context(GEC)(anonymous) is created by JS engine and is pushed onto CALL STACK and also for add function a Function execution context is created, but for the time being let us focus on only GEC. Call Stack is a stack Data Structure which is used by the engine to keep track of these execution context calls whenever it is created and destroyed. You can refer this article to know more about CALL STACK.

GEC.PNG

  1. You can see in Call Stack that anonymous is pushed onto the stack, this is nothing but GEC. In this GEC some ready made web APIs are provided by the engine which reside in Global object which you can see in scope section.

  2. Here, variables and add function are declared globally and hence these resides inside Global object. Before the piece of code I have mentioned that Execution context have two phases. So in the memory creation phase the engine scans the program from the top and assign memory to variables and functions even before a single line of code is executed, we can observe that breakpoint is at second line.

  3. The engine gives a placeholder as undefined for variables whereas for functions it assigns whole function definition as it is. From the image you can observe that a1 and a2 are assigned undefined and add function consists of its definition and some properties like name, arguments,etc. So, this was all about first phase of execution.

Let us move on to code execution phase part

FEC.PNG

Here I have added breakpoint on line 10. On first stepover value of a1 is reassigned as 5 while a2 still remains undefined. Now the control is on 3rd line. On second stepover control moves to 10th line at var sumOfNumbers = add(a1, a2); Here, a2 gets reassigned to 10 as code execution of 3rd line gets completed.

When program control is at line no. 10, I have added another breakpoint at line 6

Quick Note: You can track program controller i.e. line no where execution is at halt in call stack beside execution context as index.js:10. You can find step over function call icon just beside resume icon above breakpoints section

  1. On third stepover control moves to line 6 and here we can observe that FEC with name as add is pushed on to the call stack. This FEC is same in every manner with GEC except the fact it is local and the variables of FEC are not accessible in GEC.

  2. In this FEC, again same two phase process of memory allocation and code exection is carried out. We can observe contents of FEC in the Local object of scope section, where we have a and b arguments and sum variable. Note that sum is still undefined because code of the FEC is still not executed. We also have this object in Local which is pointing to window. But let us keep aside this this and window for some other blog.

Sum.PNG

On fourth stepover 6th line is executed and sum is evaluated and reassigned to 15, the control then goes to 7th line return sum; Now you will see something interesting after code execution of 7th line gets completed

Console.PNG

When return sum; is executed, the engine destroys or delete FEC and pops off sum from call stack. Now as FEC is destroyed hence the environment variables of that particular context is also deleted and memory is released. the control goes to console.log(sumOfNumbers); And at last when last line is executed we can see consoled value of sum on console section and control moves to 12th line.

Congratulations🎉 on reaching to end of the blog, well, I know that this was a lot to digest and one cannot understand everything on first go.

I have a task for you which will make you more clear about this concept.

Task 1:

The task is that, open up your system and run the code and use chrome dev debugger to execute each and every statement. Then compare your output with above images and observe every variable values, what all happens after function is invoked and all such stuff.

Task 2:

After you are done with this and when control is on 12th line do a step over and observe the call stack you will find something interesting again.

Now, when you are done with this, try to answer this question:

When index.js file is empty and you run it, will JS engine do some task or it will just be idle in this case. Consider finding out answer to this by running and debugging it and you will see something present in the call stack.

If you are still confused you can watch this video for in-depth explaination by Akshay Saini

Hope you enjoyed reading it!