DEV Community

Shameel Uddin
Shameel Uddin

Posted on • Originally published at blog.hasab.tech

How JavaScript Works (Part 2) – Execution Context & Call Stack Explained in Simple Words

In Part 1, we explored how JavaScript runs under the hood and discussed the JavaScript engine and runtime environment.

In this part, we’re going deeper.

We will understand:

  • What is Execution Context?
  • What are the different phases and types of an Execution Context?
  • What is the Call Stack?
  • How functions are executed internally? And most importantly we’ll visualise everything with a simple code example.

Let’s begin.

What is an Execution Context in JavaScript?

Whenever JavaScript runs your code, it creates a special environment called an Execution Context.

Think of it as a container where JavaScript keeps everything needed to execute your code.

Phases of Execution Context

Each execution context goes through two phases:

1. Creation Phase (Memory Allocation Phase)

Before executing your code, JavaScript:

  • Scans the code
  • Allocates memory for variables
  • Stores function definitions in memory

Important behavior:

  • Variables declared with varare initialized with undefined
  • Functions are stored entirely in memory
  • let and const are hoisted but kept in a temporal dead zone No code is executed here. Only memory setup happens.

2. Execution Phase

In this phase, JavaScript:

  • Executes code line by line
  • Assigns actual values to variables
  • Runs functions when invoked
  • Evaluates expressions

This is where real execution happens.

Types of Execution Context

There are two main types of execution context:

1.Global Execution Context (GEC)

  • Created when JavaScript starts running your file
  • Exists only once and stays in the Call Stack until the program closes
  • Represents the global scope

2.Function Execution Context (FEC)

  • Created whenever a function is called or invoked
  • Each function call creates a new execution context
  • Has its own memory and thread of execution

What’s Inside an Execution Context?

Thread of Execution

This is the order in which JavaScript runs your code line by line.

JavaScript is (initially) single-threaded, meaning it executes one line at a time.

Memory

Each execution context has its own memory.

  • Global context → Global memory
  • Function context → Local memory

This is why variables inside functions are not accessible outside (unless returned).

What is the Call Stack?

JavaScript uses a special memory structure to keep track of all execution contexts called the Call Stack.

It follows LIFO structure, i.e., "Last In, First Out" (like a stack of plates).

  • The last function added to the stack, will be executed first, and will be popped out of the stack first.

How all of this works: Step-by-Step!

Let’s understand this using a simple example.

const firstName = "Munzah";
const lastName = "Shah";
const age = 27;
const designation = "Software Engineer";

function createFullName() {
  return firstName + " " + lastName;
}

function displayUserDetails() {
  console.log("Full Name:", createFullName());
  console.log("Age:", age);
  console.log("Designation:", designation);
}

displayUserDetails();

Enter fullscreen mode Exit fullscreen mode

Step-by-Step Execution Breakdown

Step 1: Global Execution Context is Created

When the file runs:

  • Global Execution Context (GEC) is created
  • It is pushed into the Call Stack

Call Stack:

| Global |
Enter fullscreen mode Exit fullscreen mode

Step 2: Creation Phase of Global Context

Memory is allocated:

firstName  undefined
lastName  undefined
age  undefined
designation  undefined
createFullName  function definition
displayUserDetails  function definition

Enter fullscreen mode Exit fullscreen mode

Step 3: Execution Phase Begins

Now values are assigned:

firstName  "Munzah"
lastName  "Shah"
age  27
designation  "Software Engineer"
Enter fullscreen mode Exit fullscreen mode

Functions are still not executed just stored.

Step 4: Function Invocation Happens

When this line runs:

displayUserDetails();
Enter fullscreen mode Exit fullscreen mode

A new Function Execution Context is created.

Call Stack becomes:

| displayUserDetails |
| Global             |
Enter fullscreen mode Exit fullscreen mode

Now JavaScript executes displayUserDetails.

Step 5: Inside displayUserDetails()

The thread of execution encounters another function call:

createFullName()
Enter fullscreen mode Exit fullscreen mode

Another Function Execution ExecutionContext is created.

Call Stack now looks like this:


| createFullName     |
| displayUserDetails |
| Global             |
Enter fullscreen mode Exit fullscreen mode

Step 6: createFullName Executes

It returns:

"Munzah Shah"
Enter fullscreen mode Exit fullscreen mode

Once function is completed:

  • Its result is returned to the parent execution context.
  • And It's execution context is popped out from the stack.

So now, call Stack becomes:


| displayUserDetails |
| Global             |
Enter fullscreen mode Exit fullscreen mode

Step 7: Remaining Code In displayUserDetails() Function Executes

Now:

Age: 27
Designation: Software Engineer
Enter fullscreen mode Exit fullscreen mode

After finishing the execution of this function:

  • displayUserDetails() context is removed
  • Stack pointer goes back to Global

Call Stack:

| Global |
Enter fullscreen mode Exit fullscreen mode

Important Rule to Remember

JavaScript always executes the function that is on the top of the Call Stack.

That’s why it follows LIFO.

Final Output of This Code

Full Name: Munzah Shah
Age: 27
Designation: Software Engineer
Enter fullscreen mode Exit fullscreen mode

Why Understanding This is Important

If you understand:

  • Execution Context
  • Call Stack
  • Creation Phase
  • Execution Phase

You will easily understand:

  • Hoisting
  • Scope
  • Closures
  • Asynchronous JavaScript
  • Event Loop

And that’s when JavaScript truly starts making sense.

Summary

  • JavaScript creates a Global Execution Context (GEC) when a program starts running.
  • Every execution context goes through two phases:
  • Creation Phase (memory allocation)
  • Execution Phase (code runs line by line)
  • Variables and function definitions are stored in memory during the creation phase.
  • Each function call creates a new Function Execution Context (FEC).
  • Every execution context contains:
  • Its own memory
  • A thread of execution
  • JavaScript uses a Call Stack to manage execution contexts.
  • The Call Stack follows the **Last In, First Out (LIFO) **principle.
  • The function at the top of the stack is executed first.
  • Once a function finishes execution, it is removed (popped) from the stack.
  • The Global Execution Context remains until the program finishes running.
  • Understanding execution context and call stack makes advanced concepts like hoisting, closures, and async JavaScript easier to understand.

Stay connected with hasabTech for more information:
Website | Facebook | LinkedIn | YouTube | X (Twitter) | TikTok

Top comments (0)