CodeOath
← All posts
JavaScript75 min total · 15 parts

JavaScript Core Concepts: Scope, Closures, `this`, and the Event Loop

Contents — Part 4 of 15: Hoisting and the Temporal Dead Zone
Part 4 of 15 · ~1 min

Hoisting and the Temporal Dead Zone

Hoisting means declarations are processed before any code in that scope actually runs, but what gets hoisted — and how it's initialized — differs by declaration type.

console.log(a); // undefined — hoisted AND initialized to undefined
var a = 1;

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 2;

console.log(sayHi()); // works — function declarations are fully hoisted, body included
function sayHi() { return "hi"; }

console.log(sayBye()); // TypeError — sayBye is hoisted as a variable but not yet assigned
const sayBye = () => "bye";
  • var declarations are hoisted and initialized to undefined immediately — reading one before its assignment line gives undefined, not an error.
  • let/const declarations are hoisted but left uninitialized. The span between the start of their scope and their actual declaration line is called the temporal dead zone (TDZ) — accessing the variable anywhere in that span throws a ReferenceError, which is generally more helpful than var's silent undefined.
  • Function declarations (function foo() {}) are hoisted completely, body and all — you can call one before the line it's written on.
  • Function expressions and arrow functions assigned to let/const are not callable before their declaration, because the variable is in the TDZ even though the function itself, once assigned, works normally.