19
JavaScript Demystified: The execution context and the call stack
Hello Devs, "JavaScript demystified" is going to be a series of blogs. And this is the first one. I will try to cover the important yet not well-known javascript concepts in this blog series. I would like to start off the series by explaining the execution context and the call stack.
Execution context may be defined as the environment in which the code gets executed. Everything in JavaScript happens inside the execution context
It is composed of two components, the memory component and the code component.
The memory component, also known as the variable environment, stores the variable, functions and their values as key-value pairs.
It is also known as the thread of execution. Inside the code component, the code is executed one line at a time.
Execution context is created in two phases. The first one is memory creation phase, in this phase the interpreter skims through the whole program and allocates memory to the variables and functions. The second phase is called the code execution phase, the code gets executed in this phase.
Let's visualize this with an example. Consider the following program:
var n = 10;
function double(num){
return num*2;
}
a = double(n);
b = double(7);
When the program starts to execute, a new execution context will be created, since we are dealing with global level, it is called the global execution context.
On line number one, memory is allocated for the variable n, and it is assigned with the value "undefined". You can think of "undefined" as a special placeholder keyword (we will learn more about it in the upcoming blogs).
Then memory is allocated for double function, the whole function is assigned to it as its value.
Similar to variable n, memory is allocated for variables a and b, and they are assigned with the value "undefined"
This is how the execution context will look like:
Code is executed line by line, firstly the value of n will be replaced with 10. The function definition of double will be skipped, as it is just a definition, there is nothing to be executed. Then we reach the function invocation where double function is called. Now something interesting happens, a new execution context will be created inside the global execution context's thread of execution.
The same process will happen to this new execution context as well.
During the memory creation phase, memory will be allocated for num and will be assigned with undefined.
During the code execution phase the value of num will be replaced by 10.
When the program reaches "return" keyword, the control is returned to the function caller, along with value specified after the return keyword. Then that particular execution context is deleted. In our case, execution context of double(n)
will be deleted.
similarly double(7)
will also be executed.
Once the program reaches the end of the file, the global execution context will also be deleted.
The example we saw was pretty simple. But what if we have multiple function invocations inside a function, how will JavaScript handle it? The answer is call stack.
It is similar to the stack data structure. It follows the LIFO(Last In First Out) principle.
Whenever we start a program, the global execution context is pushed into the stack. After that if we call a function it is pushed into the stack. Once the code reaches the return statement, the function gets popped off the stack. The global execution context will be popped off when we reach the end of the file.
As we saw, JavaScript has only one call stack, hence it is single threaded. And it executes the code line by line, so it is synchronous.
But you might say, "I have used AJAX, JavaScript is asynchronous". No, JavaScript is not asynchronous. We will see how javascript handles asynchronous code in the upcoming blogs.
I hope you liked this blog, In the next blog, I will cover the concept of hoisting. Follow me to receive the notification.
Want to connect with me? You can DM on Dev.to and twitter.
19