How JS code is executed.

JavaScript code execution involves a sequence of steps managed by the JavaScript engine, primarily through the use of the call stack and execution contexts. Remember, JavaScript is a synchronous (moves to the next line only when the execution of the current line is completed) and single-threaded (can execute one command at a time in a specific order) language.

Let’s first understand about Execution content.

Execution Context

Whenever a JS file executes, the JavaScript engine creates a default Execution Context known as the Global Execution Context. Everything in JavaScript happens inside an Execution Context. You can think of it as a container where the entire process occurs.

The Execution Context has two components, and JavaScript code is executed in two phases:

  • Memory Component or Variable Environment
  • Code Component or Thread of Execution
Execution Context

Inside the Execution Context

After creating the Execution Context, two phases occur:

  • Memory Allocation Phase (Creation Phase) In this phase, the global object (browser - window, node.js - global) is created. The this object is also created and bound to the global state. All variables and functions in the code get their memory allocated with undefined and the entire function code, respectively.

  • Code Execution Phase In this phase, thread execution happens, and all variables get their assigned values. When a function is invoked, a new Execution Context is created, and the process repeats with its own memory allocation and code execution phases.

Example

Let’s dive into an example for better understanding.

var x = 10;
var y = 5;

function doSubtraction(n1, n2) {
    var sub = n1 - n2;
    return sub;
}

var sub1 = doSubtraction(x, y);
var sub2 = doSubtraction(100, 50);

When executing the above code, the Creation Phase and Execution Phase will occur as follows:

Step 1: Creation Phase
  • x variable is allocated memory and stores undefined.
  • y variable is allocated memory and stores undefined.
  • doSubtraction function is allocated memory and stores the entire function code.
  • sub1 variable is allocated memory and stores undefined.
  • sub2 variable is allocated memory and stores undefined.
Step 2: Execution Phase
  • The value of 10 is assigned to the x variable.
  • The value of 5 is assigned to the y variable.
  • The doSubtraction function is skipped for now since there is nothing to execute.
  • The doSubtraction function is invoked, creating a new Function Execution Context.
Step 3: Function Execution Context Creation Phase
  • n1 and n2 variables are allocated memory and store undefined.
  • sub variable is allocated memory and stores undefined.
Step 4: Function Execution Context Execution Phase
  • n1 and n2 are assigned the values 10 and 5, respectively.
  • The subtraction is performed, and the result (5) is stored in the sub variable.
  • The return statement sends the function’s result back to the Global Execution Context with the value 5.
  • The returned value is assigned to the sub1 variable.
  • The process repeats for the next function call (doSubtraction(100, 50)), creating a new Function Execution Context and following the same steps from Step 3.

After the Step 4, the function context created will be removed from the call stack. Then the next function call (doSubtraction(100, 50)) creates a new function execution context, and it will add to the call stack. After performing the calculation, the latest function execution context also removes from the call stack and control will go to the global execution context, which persists until the script fully completes.

Execution Context

Call stack

The call stack in JavaScript is a data structure that manages the execution orders of function calls in a last-in, first-out (LIFO) order.

The call stack is essentially a stack data structure used by the JavaScript engine to keep track of the point to which each active function should return control, when it finishes executing. When a JS program is run, the call stack is populated with this Global execution context. When a function is invoked a new function execution context is created and pushed to the stack. After the function execution it will popped out of the stack and the control reaches to the execution context below it in the stack.

call stack

Let’s explain the call stack with the above example. As you can see in the diagram, after creating global context, function execution context is pushed to the stack when the doSubtraction(x, y) invokes and it will be popped out after the execution. Similar to that, next function call (doSubtraction(100, 50)) creates a new function execution context, and it will pushed to the call stack. And it will popped out when the execution completes and control reaches to the execution context below it in the stack.

Summary

Hope you understood how JavaScript code is executing with the help of execution contexts and call stack.

  • The global execution context is the starting point of any JavaScript execution and remains at the bottom of the call stack throughout the entire execution process.
  • The global execution context has two phases: the memory allocation phase and the code execution phase.
  • In the memory allocation (creation) phase, variables are allocated memory and initialized with undefined. Functions are also allocated memory and store their entire function code.
  • In the code execution phase, values are assigned to variables. When a function is invoked, a new function execution context is created and pushed onto the call stack.
  • The call stack manages function calls, with each function call creating a new execution context that is pushed onto the stack.
  • When a function completes, its execution context is popped off the stack, and control returns to the previous execution context.
  • The call stack manages the order of function execution in a last-in, first-out (LIFO) manner.
  • After all function execution contexts are popped off, control returns to the global execution context, which persists until the script fully completes.
References

GeeksforGeeks, freeCodeCamp, YT Namastae JavaScript, Traversy

Read More