Flow Of Code Execution In JavaScript And The Execution Context
How javascript code executed, a sort discussion about JavaScript Engine, Just-in-Time compiler and a discussion about Execution Context with example.
In javascript, all the code is executed inside a javascript engine (for example V8, JavaScriptCore, SpiderMonkey etc.).
What is JavaScript Engine?
JavaScript engine is a program whose responsibility is to execute JavaScript code. It comes inside browsers(Chrome, Firefox) of servers(node, deno) to execute javascript code.
Modern javascript engines are using Just-in-Time compiler
How does the JavaScript Just-in-Time compiler work?
As a new piece of JavaScript code enters the JavaScript Engine, the first step performed is parsing the code. During this process, the code is parsed into a data structure called the Abstract Syntax Tree (AST).
The Abstract Syntax Tree first splits each line of code into pieces that are meaningful to JavaScript, such as the let
, static
, or function
keywords. It then saves these pieces of code into a tree-like structure. The next step checks whether there are any syntax errors and, if none are found, the resulting tree is used to generate the machine code.
As javascript is an interpreted language, it moves to the next line only when the execution of the current line is completed.
execution context
The entire javascript code exaction happens inside a container that is called execution context.
There are two kinds of Execution Context in JavaScript:
Global Execution Context (GEC)
Function Execution Context (FEC)
Global execution context
Whenever the JavaScript engine receives a source file, it first creates a default Execution Context known as the Global Execution Context (GEC). It represents the environment in which the top-level code is executed.
The GEC is always created, even with an empty file.
Function execution context
Whenever a function is called, the JavaScript engine creates another type of Execution Context known as a Function Execution Context (FEC) on top of the GEC to evaluate and execute the code within that function.
The Execution Context was conducted in two phases:
Memory Allocation Phase
Code Execution Phase
Memory Allocation Phase
In this phase, javascript allocates the memory to all the variables and functions present in the program. The variables are stored with the value undefined
and the function is stored with all the code present in that particular function.
Code Execution Phase
In this phase, the main execution takes place and the javascript runs through the code line by line. Here all the variables get initialized with their values. And when a new function is invoked a new execution context is created inside the GEC.
Let's take an example:
let a = 3
let b = 5
function add(a, b) {
let sum
sum = a + b
return sum
}
let sum = add(a, b)
At first, as soon as the code is invoked an execution context is created.
Variables and functions are mounted into Memory Allocation.
At this time a Call stack is also maintained by javascript, to maintain the Order of execution
of execution contexts.
Now Javascript executes code line-by-line and assigns the values.
It assigns values to variables a
and b
. At the time of function it skips that and executes the next line.
Now when the sum
variable is called the add()
function is invoked.
Because add()
function is invoked a new execution context is created.
After the creation of another execution context, the Call stack is updated.
Now in the function execution context variables a
and b
gets its value from the calling location.
At the assigned time of the sum
variable, the operation a + b
is executed in the code execution part and returns the result to the sum
variable.
After this function execution context returns the value to its calling variable.
And after FCE execution the whole execution context is deleted from GEC and Call stack is updated again.
At last after all code execution, the global execution context also disappeared.