This article is aimed at explaining 😃 what the call stack
is and why it is needed. An understanding of the call stack will give clarity to how “function hierarchy and execution order”
works in the JavaScript engine.
But before we jump the gun,🤫 let us first attempt to answer the question - What is the call stack?🤠
At the most basic level, a call stack is a data structure that uses the Last In, First Out (LIFO) principle to temporarily store and manage function invocation (call).
The call stack 🏳️⚧️
The call stack
is a mechanism JavaScript uses to keep track of functions. When you call a function JavaScript will add that function to the call stack
. If this function calls another function, JavaScript will add that function to the call stack as well, above the first function.
This process will repeat with any other function that will be called by the previous function. When one function is finished, JavaScript will remove
that function from the call stack
. There are two important things. The first thing is that every new function in the stack will be added to the top of the call stack.
The second thing
is that the call stack is executed from the top to the bottom. The last function added to the stack will be executed first. The first function added to the stack will be executed as the last. This is also called theLIFO principle (Last-In-First-Out)
.
Let’s illustrate this in code with one simple example.
function myFuncOne() {
return 'This is the end.'
}
function myFuncTwo() {
myFuncOne()
return 'Knock knock.'
}
// Call stack is still empty here
myFuncTwo()
// Call stack:
// Step 1: myFuncTwo() is invoked
// Step 2: myFuncTwo() added to the call stack
// Step 3: myFuncTwo() calls myFuncOne()
// Step 4: myFuncOne() is added to the call stack
// Step 5: myFuncOne(), is executed
// Step 6: myFuncOne() removed from the stack
// Step 7: JavaScript goes back to myFuncTwo()
// Step 8: any code left inside myFuncTwo() after myFuncOne() call is executed
// Step 9: myFuncTwo() is removed from the stack
// Step 10: call stack is empty
How does the call stack handle function calls?🤔
We will answer this question by looking at a sample code of a function that calls another function.
Here is the example code:
function firstFunction(){
console.log("Hello from firstFunction");
}
function secondFunction(){
firstFunction();
console.log("The end from secondFunction");
}
secondFunction();
This is what happens when the code is run:
- When
secondFunction()
gets executed, an empty stack frame is created. It is the main (anonymous) entry point of the program. secondFunction()
then callsfirstFunction()
which is pushed into the stack.firstFunction(
) returns and prints “Hello from firstFunction” to the console.firstFunction()
is pop off the stack.- The execution order then
move
tosecondFunction()
. secondFunction()
returns andprint
“The end fromsecondFunction
” to the console.secondFunction()
is pop off the stack, clearing the memory.
What is LIFO?🧐
When we say that the call stack
, operates by the data structure principle of Last In, First Out, it means that the last function that gets pushed into the stack is the first
to pop out, when the function returns.
Let's understand what is LIFO with a simple example
As an example, consider the following program:
void bar() {
}
void foo() {
bar();
}
int main() {
foo();
}
When the program is run, the main()
function is called, so an activation record is created and added to the top of the stack. Then main()
calls foo()
, which places an activation record for foo()
on the top of the stack. Then bar()
is called, so its activation record is put on the stack. When bar()
returns, its activation record is removed from the stack. Then foo()
completes, removing its activation record. Finally, the activation record for main()
is destroyed when the function returns.
In summary 😌
The key takeaways from the call stack are:
- It is
single-threaded
. Meaning it can only do one thing at a time. - Code execution is
synchronous
. - A function invocation creates a stack frame that occupies a temporary memory.
- It works as a
LIFO — Last In, First Out data structure
.