What is Execution context in JavaScript?

What is Execution context in JavaScript?

·

5 min read

In this article, I'll try to explain to you what is execution context and how it is created with easy examples. It is a complete beginner tutorial.

Let's guess an output first

console.log(a)
b()
bb()

var a = 10;

function b() {
   var c = 20;
   console.log(c)
}

var bb = () => {
   var cc = 30;
   console.log(cc)
}

Output will be

ececutionContext.png If you guessed it right then you have a good understanding of how javascript code is run under the hood.

For those who were unable to guess it right, let's first understand what is execution context.

Let me start with the core fundamental, i.e

Everything in javascript happens inside an execution context.

It is like a big box, in which it has two components

  1. Variable Environment (memory component)
  2. Thread of Execution (code component)

EVENTloopMADE1.jpg

In the variable component, memory is allocated to all the variables and function present in the code and stored as key-value pair.

In the code component, the actual code is run line by line from top to bottom, as it is written by the user.

Now let's take a simple code example and see how this execution context is created.

var a = 10;

function b () {
   var c = 20;
   console.log(c);
}

console.log(a);
b();

First, a Global execution context(GEC) is created and is put inside the call stack.

Global execution context is created in two-phase

1. First is memory allocation(compile phase)

Line1 - Engine sees a variable a, allocates memory to it, and gives an initial value undefined to it.

Line3 - Then it sees a function b, allocates memory to it but for functions, it is a little different, it literally copies the whole function and stores it in the value.

No other variable and function present, so phase 1 is complete. Ya Ok, you might me thinking there is another variable c inside the function b, what happened to that?. The variable c is inside a function scope so it will not be stored inside the global scope. We will see this later below.

Let me put a debugger on line 1 to show how it looks like in a browser. debug1EDIT.jpg

This memory allocation is called Hoisting

Hoisting: the variable and function declarations are put into memory during the compile phase.

2. Second is code execution phase

Now javascript once again runs through the code line by line. This is the phase where all functions and calculations are executed.

Line1 - Now the engine replaces the value undefined and assigned a value 10 to the identifier a.

now it directly moves to line 8 as no variable or no function is invoked between line 2 to 7

Line8 - Executes the line and prints 10 in the console.

Line9 - Function b is invoked. Whenever a function is invoked a new local execution context is created inside the execution context where it was invoked and it is put inside the call stack.

Line3 - Then again, this local execution context is created in two-phase.

- Memory allocation: Variable c is allocated a memory with value undefined

EVENTloopMADE11.jpg

Line4 - Code inside the function b is executed

- Code execution: C is assigned a value 20

Line5 - Executes the line and prints 20 in the console

once the entire function execution is complete, the local execution context vanishes and it is also popped out of the call stack. And the control is back to line 9

EVENTloopMADE2 - Copy.jpg

And after the entire code is completely executed, the global execution context is also popped out of the call stack

Now let's go back to the first example we took.

console.log(a)
b()
bb()

var a = 10;

function b() {
   var c = 20;
   console.log(c)
}

var bb = () => {
   var cc = 30;
   console.log(cc)
}

let me go through the execution of the above javascript code

Phase1: Memory allocation

First memory is allocated to all the variables and functions in the memory component of the global execution context.

debug2EDIT.jpg here you can see function bb and function b has different values. One has undefined and the other has the entire function. Why this?

This is because b is a function statement & bb is a function expression. The one difference is that, how these both functions are hoisted.

Function b is hoisted as a normal function

Function bb is hoisted as another variable. So it is assigned a value undefined.

Phase2: Code execution

Now when the engine starts to execute the code from top to bottom.

Line1: - Prints the value of variable a as undefined. Because we now know that the variable a will be assigned a value of 10 at Line5

Line2: - Function b is invoked. A new local execution context is created and put inside the call stack. Control moves to Line 7 and again the entire process occurs to create the local execution context. And then its Prints the value of variable c as 20. Control then again moves to Line2

Line3: - As bb is stored as a variable. We cannot invoke it as a function. So the error is thrown on the console as Uncaught TypeError: bb is not a function

Now no variables or functions are invoked further in the code. So the execution is complete and the global execution context is also popped out of the call stack

So the output will be ececutionContext.png

Conclusion

In this article, we learned what is execution context, how it is created, and also what is hoisting. So now you can use the concept of execution context to analyze any code and how it will be executed under the hood and can predict the write output.

Thank you for reading the blog😍. If you liked it, please share it with your developer friends who might find it useful too.