GUIDE TO JavaScript EXECUTION CONTEXTS, HOISTING, SCOPES, AND CLOSURES
Published: 2023-12-20 11:38:29


**Introduction**
Understanding JavaScript goes beyond writing code, it's about grasping the fundamental concepts that govern its behavior. In this guide, we'll explore Execution Contexts, Hoisting, Scopes, and Closures – crucial concepts that form the backbone of JavaScript's execution model.

**Execution Contexts: Breaking Down Complexity**
JavaScript's strategy for interpreting and running code involves breaking it into manageable pieces called Execution Contexts. These contexts act as containers, allowing the JavaScript engine to handle code complexity efficiently. The first context that emerges is the "Global Execution Context," consisting of a global object and a 'this' variable referencing the global object.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omng7uxue1it2dc41vuv.png)

Even without code, the Global Execution Context creates a window object and a 'this' object.

**Execution Context Phases: Creation and Execution**

Each Execution Context has two phases: Creation and Execution. During the Global Creation phase, the engine:

Creates a global object.
Creates a 'this' object.
Sets up memory space for variables and functions.
Assigns variable declarations the default value 'undefined' and places function declarations in memory.

**// Code**
// Global Creation phase
console.log(name);      // Output: undefined
console.log(handle);    // Output: undefined
console.log(getUser);   // Output: ƒ getUser() {}

var name = "Mohit";
var handle = "@mohitwadhwa ";

function getUser() {
  return { name: name, handle: handle };
}

This process of assigning variable declarations the default value during the Creation phase is known as **Hoisting**.

**Function Execution Context: Creating on Demand**
The Function Execution Context is created when a function is invoked, with similar steps as the Global Execution Context. However, it skips creating a global object and focuses on arguments.

**//Code**
// Function Execution Context
function exampleFunction(arg) {
  console.log(this);      // Output: [object Window]
  console.log(arguments); // Output: { '0': 42 }
}
exampleFunction(42);

**Scopes: Where Variables Thrive**
Scopes, defined as "the current context of execution," are intimately tied to Execution Contexts. Variables are locally scoped within functions, and each Execution Context has its unique variable environment.

**//Code**
// Local scope example
function foo() {
  var bar = "Declared in foo";
  console.log(bar); // Output: Declared in foo
}
foo();
console.log(bar);   // Output: ReferenceError: bar is not defined

**Scope Chain: Navigating Variable Hierarchies**
Variables are accessible within their scope, and the JavaScript engine follows the Scope Chain. If a variable isn't found locally, the engine looks up the chain until it reaches the Global Execution Context.

**//Code**
// Scope Chain example
var name = "Mohit";

function logName() {
  console.log(name); // Output: Mohit
}
logName();

**Closures: Preserving Parental Bonds**
Closures occur when a child function retains access to its parent function's scope, even after the parent's Execution Context is removed from the stack.

**//Code**
// Closures example
function makeAdder(x) {
  return function (y) {
    return x + y;
  };
}

var addFive = makeAdder(5);
console.log(addFive(3)); // Output: 8

Closures preserve the variable environment, allowing inner functions to access outer functions' scope.