Simplest Explanation : How JavaScript Executes code Behind the scenes?
Photo by Juanjo Jaramillo on Unsplash
What is JavaScript?
" javascript is a synchronous, single-threaded language"
JavaScript is a popular programming language that runs on a variety of platforms and browsers. It is a synchronous, single-threaded language, meaning that it can only execute one line of code at a time.
When JavaScript code is executed, the engine creates an execution context and pushes it onto the call stack. The execution context includes the variable environment and the thread of execution.
Global Execution Context
JavaScript engine creates a special environment to handle the transformation and execution of this JavaScript code. This environment is known as the
Execution Context
The global execution context is created when the engine starts running, and it includes the variable environment (Memory) and the thread of execution(code), The variable environment is responsible for setting aside memory space for variables and functions, and the thread of execution executes the code line by line.
There are two kinds of Execution Context in JavaScript:
Global Execution Context (GEC), (Local) Function Execution Context (FEC)
The GEC is the base/default Execution Context where all JavaScript code that is not inside of a function gets executed.
For every JavaScript file, there can only be one GEC.
Whenever a function is called, the JavaScript engine creates a different type of Execution Context known as a Function Execution Context (FEC) within the GEC to evaluate and execute the code within that function.
Since every function call gets its own FEC, there can be more than one FEC in the run-time of a script.
How does Code Execution work?
Role of the thread of execution and variable environment
This has two phases :
Memory creation phase
Code execution phase
Memory Creation phase
During the memory creation phase, the engine scans through the code to identify any variables or functions that need to be allocated memory. At this point, it sets aside memory space for each variable and function but does not yet assign any values to them. This phase also creates a scope chain, which is used to resolve variable references.
After the memory creation phase, the memory allocation begins. At this point, each variable is assigned a value of undefined as a placeholder, and functions are stored as the whole code.
- The variable environment is where variables and functions are stored during the creation phase. In this phase, all variables and functions are created and stored in memory, but not yet assigned a value. When a variable is declared, it's stored in memory with the value of undefined.
picture:
Code exectuion phase
Next, the thread of execution comes into play. It is responsible for executing the code line by line, in order. As each line of code is executed, the engine updates the values of the variables and executes any functions that are called. If any function is called, it creates a new execution context for that function and pushes it onto the call stack.
The call stack keeps track of all the execution contexts that are currently in progress. It follows a Last In, First Out (LIFO) order, meaning that the most recently added context is the first to be executed.
Once a function is finished executing, its execution context is removed from the call stack, and the engine continues executing the code from the point where the function was called. The call stack continues to push and pop execution contexts until the program is finished.
Call Stack :
The Call Stack is a mechanism based upon data structure records where in the program the execution is currently at. Every time a function is called, a new execution context is created and pushed onto the call stack. When the function finishes executing, the execution context is popped off the stack, and the program continues from where it left off.
if call stack becomes too large, it can cause a stack overflow error. This occurs when there are too many nested function calls and the call stack becomes full.
window object
In addition to creating the variable environment and the thread of execution, the global execution context also creates a global object. In web browsers, this global object is commonly referred to as the window object. 'this' is attached to this window object.
All variables declared with the var keyword in the global scope are attached to the window object.
For example, consider the following code:
var name = "John";
console.log(window.name); // outputs "John"
console.log(this.name); // outputs "John"
console.log(this===window); //true
In this code, the variable
name
is declared in the global scope using thevar
keyword. Since it's declared in the global scope, it becomes a property of thewindow
object. The code then logs the value of thewindow.name
to the console, which outputs the string "John".- Note that this behaviour applies only to variables declared with the
var
keyword. Variables declared withlet
orconst
in the global scope are not attached to thewindow
object.
- Note that this behaviour applies only to variables declared with the
Execution Context and Scope
Every execution context has a scope chain, which is a list of variables and functions that the execution context has access to. When the JavaScript engine looks up a variable or function, it starts at the current execution context and works its way up the scope chain until it finds the variable or function.
The scope chain is determined by the way in which functions are defined. When a function is defined, it retains a reference to the variables and functions in its outer environment, which creates a chain of nested environments. This is known as lexical scoping.
Conclusion
In conclusion, understanding execution contexts is key to understanding how JavaScript code runs. Every time JavaScript code is executed, it's executed in a certain context, and every context has its variable environment and thread of execution. By understanding execution contexts, you can better understand how JavaScript code is executed and how variables and functions are scoped.
I hope this article has helped you understand the basics of execution contexts in JavaScript. With this knowledge, you can write more efficient and optimized JavaScript code.