DEV Community

Faiz Mansuri
Faiz Mansuri

Posted on

Debunking “Hoisting” – It’s Not Lifting, It’s Contextual Initialization

Ever logged console.log(myVar) only to see undefined… then tried the same with let and got a ReferenceError? You’re not alone. Let’s deep-dive into JavaScript’s Global Execution Context (GEC) and Function Execution Context (FEC) to demystify what’s really happening.


“Hoisting” isn’t a cosmic elevator pulling your variables up. It’s JavaScript establishing contexts before execution—and initializing some names differently.

Global Execution Context (GEC)

  • What it is: The environment created when your script first runs (e.g., window in browsers, global in Node.js).
  • Variable instantiation:

    • var names get declared and initialized to undefined.
    • let/const names are registered but not initialized—enter the Temporal Dead Zone (TDZ) until their definition line.
// In GEC:
console.log(myVar);   // → undefined  
console.log(myLet);   // → ReferenceError (TDZ)  
var   myVar = "A";    
let   myLet = "B";    
Enter fullscreen mode Exit fullscreen mode

Function Execution Context (FEC)

  • What it is: A fresh context created each time a function is called, with its own scope chain and this binding.
  • Hoisting behavior inside FEC:

    • Function declarations are fully hoisted—you can call them before they appear.
    • Inside that FEC, var again initializes to undefined; let/const stay in TDZ until their line.
// FEC for chase():
chase();  // Works, because function chase is hoisted

function chase() {
  console.log("In chase, myVar is:", myVar);        // undefined
  console.log("In chase, myLet is:", myLet);        // ReferenceError (TDZ)
  var   myVar = "inside chase";
  let   myLet = "also inside chase";
  caught();  // Also works—caught() is hoisted too
}

function caught() {
  console.log("Caught!");
}
Enter fullscreen mode Exit fullscreen mode

Temporal Dead Zone (TDZ) Quick Demo

{
  console.log(blockVar);   // ReferenceError – still TDZ!
  let blockVar = "Hello, TDZ!";
}
Enter fullscreen mode Exit fullscreen mode

⏳ Until the let line runs, blockVar exists but is inaccessible.


Top comments (0)