Execution Context and Call Stack in JavaScript

Execution Context and Call Stack in JavaScript

In this article we will be discussing execution context in JavaScript which is I guess is one of the fundamental concepts of JavaScript.

What is Execution Context?

If we go down by the MDN definition:

Execution context is a concept in the language spec that—in layman's terms—roughly equates to the 'environment' a function executes in; that is, variable scope (and the scope chain, variables in closures from outer scopes), function arguments, and the value of the this object

Let's Simplify this:

Before we get into the Execution Context, we must keep a note that

"Everything in JavaScript happens inside an Execution Context"

In other words, Execution Context is just an enviornment where JavaScript code executes.

The execution context consist of two parts:

execution-context.PNG

Memory Component: Memory component is the place where the variables and function are stored as key-value pairs. Memory Component is also known as Variable Environement.

Code Component: This is the place where JavaScript code is parsed and gets executed on a line-by-line meaning in synchronous manner, That is why Code Component is also known as Thread of Execution.

Types of Execution Contexts:

Global Execution Context:

This is the default Execution Context in JavaScript which gets executed when the file first gets loaded in the browser. There can only be Global Execution Context as only one Global Environment is possible for JavaScript Code because the JavaScript Engine being single-threaded.

Function Execution Context:

This Execution Context gets created as soon as JavaScript Engine encounters a function call. Each function has it's own Execution Context. Function Execution Context always has access to Global Execution Context.

Eval:

This is the Execution Context inside Eval function.

Call Stack:

Call Stack is a data-structure for maintaining execution contexts. In other words, Call Stack is a structure that maintains the "order of execution" of execution contexts.

Let's understand Execution Context and it's phases through an example:

carbon.png

As soon as the above code loads up in the browser, JavaScript Engine creates a Global Execution Context and pushes it's reference to the Call Stack.

The Execution Context gets created in two phases:

Memory Creation Phase: In this phase the JavaScript Engine skims through the entire JavaScript code looking for variables and functions and stores them as key-value pairs in Memory Component(Variable Environment). The variables are assigned the value of 'undefined' where as the functions are assigned with their respective function definitions.

At the end of Memory Creation Phase, the Execution Context for above example will look like below:

execution-1.PNG

Point to Note: The variables and functions are allocated memory even before a single line of code is being executed.

Code Execution Phase: In this phase JavaScript engine executes the code on a line-by-line basis meaning one line at a time. It is in this phase where the variables are assigned the values actually supplied for them.

What happens when the first line is executed for above example:

firstCode.PNG

the value of n is now set to 10 which was 'undefined' earlier

excution-line-1.PNG

now the control moves to the next line:

code-2.PNG

As there is nothing to execute in the function definition part, the control now moves to sumTen variable:

code-3.PNG

Now here JavaScript engine encounters a function call, as we read earlier that a new execution context gets created as soon as JavaScript engine encounters a function call, a new execution context is created by JavaScript Engine and it's reference is pushed to the call stack.

Again, a Memory Creation Phase will happen, where JavaScript Engine will skim through the function code, looking for variables local to that function and any other function definitions inside it. The local variables will again be assigned 'undefined' and will be stored as key-value pairs and functions (if any) too will be stored with their respective definitions.

The Global Execution Context looks like this after this:

ec-2.PNG

The Coding Execution Phase will take place, and the variables will be assigned the actual values supplied to them.

  • Here in the above example, variable num will be assigned the value of 10 passed to it.

  • The variable ans will be assigned the value of 20 after the calculation.

The Global Execution Context will look like this:

gec-1.PNG

  • As there are no lines to be executed, JavaScript engine returns the value stored in variable ans.

  • As soon as the value returns, the execution context of function doSum gets deleted from the memory and it's reference also gets popped off from Call Stack.

  • The returned value gets assigned to the variable sumTen.

gec-2.PNG

  • Now as the control moves to the next line, another function call gets encountered by JavaScript Engine, So a new Execution Context gets created for the new function call and the whole process repeats.

In the end, As the entire code is now being executed and there are no other lines left the Global Execution Context gets deleted from the memory and it's reference also gets pops off the Call Stack.