Javascript: The Call Stack and Scope

Ryan Leibering
5 min readFeb 25, 2022

The Call Stack, or just “the Stack”, is a core concept beginning developers may find difficult to comprehend. Join me on a visual journey into the Stack, where we will explore the First-In-Last-Out interpretation process and how this mechanism creates Scope.

The Call Stack

The Stack is a mechanism for interpreted languages, like Javascript, which keeps track of a machine’s place in a script and represents the static memory of a machine.

Snippets of code are are queued in a First-In, Last-Out order. Think of it like stacking boxes. We won’t be able to remove the first box until we remove any boxes we later placed on top of that box and we will have to search the top box before we can search the ones below. This is important to keep in mind as we explore the way our programs organize and access data.

Order of Operations

When a Javascript program begins, the machine will run two passes over the script. During the first pass, all global variables and functions are declared on the Stack, where memory is allocated for each item. If the item is a variable, the variable will remain undefined. If the item is a function, the entire function’s code will be defined inside the allocated memory item. On the second pass, the machine will define any undefined items in the Stack.

Using the code snippet below, follow along with the process:

In the first pass, the machine will declare each global variable on the Stack. The visual representation below shows line 1, where we add the variable friend with the const key word. It is a variable, so we will leave it as undefined as we add the item to the stack.

Our machine then adds age from line 3, using the let keyword, and the function canFriendDrink, from line 5, to the Stack.

The variable age will remain undefined but, because canFriendDrink is a function, the entire function code is defined and stored in the call Stack function item.

Lastly, the final global variable, canDrink, is added to the Stack. It will remain undefined, like the other two variables at the bottom of the stack.

Once the machine reaches the end of the script, it will start at the beginning of the script again, defining each variable that hasn’t already been defined. The way this is done is by adding an evaluation to the top of the stack which then passes the information into the corresponding variable items.

The function canFriendDrink is already defined so we skip over that item and move on to the last variable, canDrink. Now we have to define it by calling the function canFriendDrink, which gets added on top of the Stack.

Now that a function has been called, the machine goes down the stack and searches for an item with that name. Because the item is a function, the Stack moves from the global frame into the local frame and begins declare all of the variables and functions in canFriendDrink, leaving the variables undefined but passing any function code into corresponding function definitions.

Inside of canFriendDrink is a single variable, the friendAge parameter, which is declared but undefined. Once the declaration pass is completed, the machine will define friendAge which is set equal to the age variable. This must be evaluated though, so age is called to the top of the Stack for evaluation.

The machine goes down the items in the Stack, searching for age and finds the variable, returning the definition of 31 and popping off the Stack. This is passed into friendAge and the machine reads the code for additional instructions. In this case, the instruction is to return a value.

The return is evaluated to true and breaks out of the current frame, popping it off the stack and passing true into the call for the canFriendDrink function. The function call is evaluated and so pops off the call stack and passes true into the canDrink variable.

Now that all items in the global scope have been defined, the machine will look to see if any additional instructions exist. Because no additional instructions exist, each item will be evaluated and pop off the Stack, ending the program when nothing is left.

Scope

Because the Stack represents what is held in the static memory, Scope is a result of the addition and removal of items to the Stack. Function variables only exist in the Stack during a call so those items cannot be referenced unless the parent function is actively being called and evaluated by the Stack.

Resources

MDN Web Documents — Call Stack

Wikipedia — Call Stacks

A special thanks to Akshay Saini for his fantastic video on the topic:

--

--