Site icon Teaching Newbies since 2014

What is the Callstack: a gentle introduction

What is the call stack?

An understanding of the callstack will allow you to understand how execution order in JavaScript works. JavaScript is a single-threaded language; this means that it handles one task at a time. JavaScript code is executed by the JavaScript engine. Google’s V8 engine is an example of a popular JavaScript engine, there are others such as the SpiderMonkey and Rhino. The most popular host environment for the JavaScript engine to run is in the browser.

The V8 engine is written in C++. It is an open-source, high-performance JavaScript and Web Assembly engine. The V8 engine has two main parts:

  1. Heap: The heap is an unstructured memory that is used for memory allocation of variables and objects
  2. Stack: The stack is used for function calls and it records where we currently are in the program

Since JavaScript only handles one task at a time, as such it has a single call stack. The call stack is mainly using for function calls. Functions are executed from top to bottom, one at a time. A call stack is a dynamic data structure that follows the Last-In Last-Out (LIFO) principle. Its goal is to record where in the program we currently are. The LIFO principle temporarily stores and manages function invocation.

When we say that the call stack applies the LIFO principle to function invocation, this means that the last function to be pushed into the stack is the first to be popped out from the stack, when the function returns.

Last pancake on the stack is the first one on the plate:

Let’s have a look at an example:

function functionOne() {

throw new Error('Stack Trace Error');

}

function functionTwo() {

functionOne();

}

function functionThree() {

functionTwo();

}

functionThree();

The following will be returned:

Notice that the order of the functions logged to the console:

  1. functionOne
  2. functionTwo
  3. functionThree

functionOne which is the last function to be called (from within functionTwo) is the first function out and logs an error. This is followed by functionTwo. Lastly, functionThree is logged, which is the first function to be pushed onto the stack during execution. This demonstrates the LIFO principle. The last function to be pushed into the stack (functionOne) is the first one to be popped from the stack. And the first function to be pushed into the stack is the last one to be popped from the stack.

When a function is invoked, its arguments and variables within the function are pushed into the stack. An entry in the call stack is called a stack frame. A stack frame is a memory location within the call stack. Once the function is popped off the stack, the memory is cleared.

The call stack manages function invocation as it keeps a record of the position of each function call (stack frame) as functions get pushed and popped from the call stack. This record-keeping is what makes code execution synchronous. As the position of the next function to execute is known in advance.

Let’s have a look at another example:

function function1(){

console.log('function 1');

}

function function2(){

function1();

console.log('End of function 2');

}

function2();

The order of the messages logged to the console is:

"function 1"

“End of function 2"

Let’s deconstruct what is happening:

Thus the call stack by managing function invocation knows the execution order of functions and code is executed line by line, synchronously.

You might have heard of the term stack overflow. The stack is said to overflow when a function calls itself repeatedly from within itself (a recursive function). For example:

function hello(){

hello();

}

hello();

The following will returned:

Recursive functions as hello() will cause the stack to overflow. This happens when there is no exit condition and a function repeatedly calls itself. The browser’s call stack has a maximum call stack size that it can accommodate before it throws an error, as seen above in the example.

Exit mobile version