JavaScript code Execution on a deeper level
This article will give you a high level understanding of how code is executed in javaScript.
JavaScript Engine
Java Script engine executes javaScript.
Implements Heap,Call stack,Event loop,and Message queue
Interacts with web api like
settimeout
andsetinterval
Example of JavaScript engine is V8 engine that is developed by google for chrome. V8 engine github
Chakra is developed by microsoft for edge. Chakra
Heap :
The heap is a dynamic, unstructured memory space used to store objects and functions in JavaScript.
This makes it ideal for storing data whose size is unknown at compile time or changes during runtime, like arrays, complex objects, and functions themselves.
Call stack
Call stack is a data structure that is used to manage function calls and execution context in js engine
you can also imagine it like a stack data structure (LIFO).
The call stack is limited in size. Stack overflow errors occur when too many functions are called recursively or nested deeply.
The call stack manages function execution context and short-lived data, while the heap handles long-lived objects.
Message queue
Message queue is a data structure that is use to keep track of events and callbacks waiting to be processed by call stack in a First in First out manner.
This process allows JavaScript to handle asynchronous operations without blocking the main thread. Promises, callbacks, and other asynchronous patterns utilize this mechanism to ensure non-blocking behavior.
The message queue is populated whenever a browser event occurs and there is a listener attached to it. Clicking on an element with a click handler and using
setTimeout
both fall under this category.
Event loop
- The event loop constantly tries to move messages from the message queue into the call stack to be processed. It does this by polling for messages in the queue and pushing them into the call stack if the call stack is empty.
How JavaScript is executed ?
Global Execution context Creation
When a JavaScript program starts running, it creates the global execution context. This context consists of two phases: the memory phase and the execution phase.
Memory Phase
During the creation phase, the JavaScript engine sets up the global object (which is the window object in a browser environment), the 'this' keyword, and the outer environment reference. It also scans through the code and sets up memory space for variables and functions through a process called "hoisting." Variables are set to undefined, and functions are stored in their entirety.
Memory space is allocated for variables and functions.
Function declarations are placed into the allocated memory space.
Variable declarations are placed into the allocated memory space and assigned a default value of
undefined
.The
this
binding is created.Execution Phase
After the creation phase, the execution phase begins. This is where the actual code is executed line by line.
Function Execution
When a function is called, a new execution context is created for that function. This includes its own memory space for variables and parameters. The function goes through its own creation and execution phases. After the function finishes executing, its execution context is popped off the call stack.
Global Execution Completion
Once the global execution context completes, the program finishes its execution.
๐ Note: The returned value being passed to the global environment, it's more accurate to say that the returned value is passed to the calling context. If a function is called within another function, the returned value is typically used in the context of the calling function.
Example:
var n = 5;
function sum(n) {
var res = n + n;
return res;
}
var sum1 = sum(n);
var sum2 = sum(8);
console.log(sum1);
console.log(sum2);
At the very beginning, the JavaScript engine executes the entire source code, creates a global execution context, and then does the following things:
The code starts executing in the global execution context.
Sets up a memory for storing variables and functions.
Stores the variables with values as undefined and function references.
After this creation phase, the execution context will move to the code execution phase.
In Execution Phase code is executed line by line.
when it reaches line n = 5 it will assign 5 to n in the memory. Untill now n was undefined.
Then we get to the 'sum' function. As the function has been allocated in memory, it directly jumps into the line var sum1 = sum(n);. sum() will be called and JavaScript once again will create a new function execution context.
Once the calculation is done, it assigns the value of
n+n
in theres
variable that was undefined before. The function will return the value, and the function execution context will be destroyed.The returned value from sum() will be assigned on sum1. This happens for sum2 also. Once the entire code execution is done completely, the global context will look like this and it will be destroyed also.Call stack image for first call of sum(n)
When execution of sum() will get complete it will be popped out of stack. same will happen for second call of sum().
Conclusion
JavaScript code begins with the creation of the global execution context. Following this, the memory phase takes charge, where all variables are initially set to undefined, and functions are allocated memory references.
Subsequently, the execution phase kicks in, executing the code line by line. Understanding this process isn't just a valuable asset; it's a power boost for JavaScript developers. It instills confidence and clarity in JavaScript programming.
Thank you for taking the time to explore this article. We hope it has provided valuable insights into the inner workings of JavaScript. Don't hesitate to share it with your friends and colleagues.
Happy coding! ๐
Subscribe to my newsletter
Read articles from Hitendra Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Hitendra Singh
Hitendra Singh
I am a Full Stack Developer