JavaScript Execution Context

JavaScript code runs in a structured environment known as the execution context. This concept is key to understanding how variables, functions, and the scope chain behave in JavaScript. When you grasp how JavaScript creates and manages execution contexts, you'll write more predictable and bug-free code.

What is Execution Context in JavaScript?

An execution context is the environment in which JavaScript code is evaluated and executed. It contains details about the currently running code, such as variables, functions, and the value of this.

Types of Execution Context

  • Global Execution Context (GEC):
    Created by default when JavaScript starts executing. Variables and functions declared outside any function live here.
  • Function Execution Context (FEC):
    Created each time a function is called. Every call has its own context.
  • Eval Execution Context:
    Created by the eval() function (rarely used and not recommended).

Phases of Execution Context

Each execution context runs through two main phases:

Creation Phase

  • Allocates memory for variables and functions.
  • Variables are initialized with undefined.
  • Functions are hoisted into memory.
  • Scope chain and this are defined.

Execution Phase

  • Code executes line by line.
  • Variables are assigned actual values.
  • Functions are invoked.

How JavaScript Handles Memory in Each Phase

JavaScript processes code in two phases: Creation and Execution. During these phases, it allocates memory and runs code line by line.

Example:

var name = "Aman";

function sayHello() {
  var greeting = "Hello, " + name;
  console.log(greeting);
}

sayHello();

Global Execution Context

Creation Phase:

Identifier Value
name undefined
sayHello function(){...}

Execution Phase:

Identifier Value
name "Aman"
sayHello function(){...}

sayHello Execution Context

Creation Phase:

Identifier Value
greeting undefined

Execution Phase:

Identifier Value
greeting "Hello, Aman"

Output:

Hello, Aman
  • name is accessed from the global scope.
  • console.log(greeting) prints the output.

The Execution Stack (Call Stack)

JavaScript uses a call stack (also called execution stack) to manage execution contexts. When a function is called, its execution context is pushed onto the stack. When the function finishes, it's popped off the stack.

Example:

function start() {
  console.log("Start");
  process();
  console.log("End");
}

function process() {
  console.log("Processing...");
  complete();
}

function complete() {
  console.log("Complete");
}

start();

Execution Order:

  1. Global context is created.
  2. start() is called → its context is pushed to the stack.
  3. Inside start(), process() is called → new context pushed.
  4. Inside process(), complete() is called → new context pushed.
  5. complete() runs and is popped off.
  6. process() finishes and is popped off.
  7. start() finishes and is popped off.

Output:

Start
Processing...
Complete
End

This stack-based execution ensures functions are completed in a last-in, first-out manner.


Execution Context Example with Nested Functions

var city = "Delhi";

function showCity() {
  var landmark = "India Gate";

  function display() {
    console.log(city);     // Accesses from global context
    console.log(landmark); // Accesses from showCity() context
  }

  display(); // Execution context for display()
}

showCity(); // Execution context for showCity()
  • Each function gets its own execution context.
  • Lexical scoping allows inner functions to access variables from outer contexts.

Explanation:

  • Global context holds city and showCity.
  • When showCity() runs, a new context is created.
  • display() accesses both city and landmark due to lexical scoping.
  • JavaScript uses the scope chain to look up variables from outer contexts.

How JavaScript Handles Hoisting

In the creation phase, JavaScript hoists declarations to the top of their scope.

Example:

console.log(age); // undefined due to hoisting
var age = 25;
  • age is hoisted as undefined.
  • Value 25 is assigned during the execution phase.

Function Declarations (Hoisted Fully)

greet(); // Works due to hoisting

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

Function Expressions (Not Hoisted)

sayHello(); // TypeError

var sayHello = function() {
  console.log("Hi!");
};

Key Takeaways

  • Execution context defines how JavaScript runs your code.
  • It goes through creation and execution phases.
  • JavaScript uses a call stack to manage execution order.
  • Variable and function declarations are hoisted in the creation phase.
  • A strong grasp of context helps avoid scope and hoisting issues.

Conclusion

In this tutorial, you learned how JavaScript runs code using execution contexts, which go through a creation phase for memory allocation and an execution phase for running logic. You explored the global and function contexts, understood hoisting behavior, and saw how the call stack manages the order of execution. By visualizing memory step by step, you now better understand how JavaScript handles variables, functions, and scope during code execution.



Found This Page Useful? Share It!
Get the Latest Tutorials and Updates
Join us on Telegram