šŸš€ JavaScript's Secret Engine: Mastering Execution Context and Call Stack

K ManojK Manoj
4 min read

šŸŽ¬ Introduction

Why do some variables seem to exist before you declare them? How does JavaScript keep track of which function is currently running? The answers lie in understanding two fundamental concepts: execution context and the call stack.

If JavaScript were a theater, the Execution Context would be the stage where every function performs, and the Call Stack would be the backstage queue organizing who performs next.

🧠 What is Execution Context?

Execution context can be thought to be Javascript’s workspace for executing your code. We can term it to be an environment that contains everything needed to run that code—variables, functions, scope, and more.

The execution context is like a container that holds:

  • Variables and their values

  • Functions that are available

  • The scope chain (what variables can be accessed)

  • The value of this

Without execution context, JavaScript would be like a chef trying to cook without a kitchen—nowhere to store ingredients, no workspace, and no way to keep track of what's being prepared.

🧱 The Three Types of Execution Context

1. Global Execution Context (GEC)

This is the default context created when your Javascript file is first executed. There's only one global execution context per program.

2. Function Execution Context (FEC)

Created every time a function is called. Each function call gets its own fresh execution context.

function newContext() {
    var localVar = "I'm local!";
    return localVar;
}

// Each call creates a new Function Execution Context
newContext(); // FEC #1
newContext(); // FEC #2

3. Eval Execution Context

Created when code is executed inside an eval() function. Since eval() is generally avoided in modern JavaScript, we can avoid this one.

ā³ The Two Phases of Execution Context

Every execution context goes through two distinct phases:

Phase 1: Creation Phase

Before any code executes, JavaScript sets up the environment:

During creation:

  • Variables are declared and initialized to undefined

  • Functions are fully hoisted and available

  • this binding is determined → JavaScript figures out the value of this when it creates the execution context — and this depends on how the function is invoked.

    šŸ’”
    In JavaScript, the this keyword refers toĀ an object. The this keyword refers to different objects depending on how it is used: In an object method, this refers to the object. Alone, this refers to the global object. In a function, this refers to the global object.

    Note: We’ll learn about this in a later blog. For now, this vague idea should help.

  • Scope chain is established

    šŸ’”
    JavaScript builds a reference chain of all accessible variable environments (lexical scopes) for that context, so it knows where to look when resolving variables.

    Note: We’ll learn about scope chain in a later blog. For the time being, this should suffice.

Phase 2: Execution Phase

Now JavaScript runs your code line by line, variables get assigned real values and the functions execute.

šŸ“ The Call Stack: JavaScript’s Task Manager

The call stack is JavaScript's way of keeping track of where it is in your program. Think of it as a stack of plates—you can only add or remove plates from the top. This can be visualized as a data structure following the LIFO (Last In, First Out) principle.

When a function is called:

  • A new execution context is created.

  • It is pushed onto the call stack.

  • Once done, it’s popped off the stack.

function greet() {
  console.log("Hello");
}

function sayHi() {
  greet();
}

sayHi();

Now let’s look how the Call Stack works ;

Step 1: Global Execution Context is pushed.

Step 2: sayHi() context is pushed.

Step 3: Inside sayHi(), greet() is called → pushed.

Step 4: greet() logs ā€œHelloā€ → popped.

Step 5: sayHi() finishes → popped.

šŸ Conclusion

JavaScript might be a high-level language, but under the hood, it’s hard at work managing execution contexts and juggling functions on the call stack. Understanding how the execution context is created and how the call stack operates gives you a deeper appreciation for how your code actually runs.

Next time your code behaves unexpectedly, don’t forget to peek behind the curtain. šŸ˜‰

10
Subscribe to my newsletter

Read articles from K Manoj directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

K Manoj
K Manoj

Backend Web Developer | Security Enthusiast |