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 toundefined
. -
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";
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 toundefined
;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!");
}
Temporal Dead Zone (TDZ) Quick Demo
{
console.log(blockVar); // ReferenceError – still TDZ!
let blockVar = "Hello, TDZ!";
}
⏳ Until the let
line runs, blockVar
exists but is inaccessible.
Top comments (0)