Hoisting

⭐ Interview Importance: HIGH
⏱️ Revision Time: 3 min

TL;DR

Hoisting is JavaScript’s behavior of putting variable and function declarations into memory during the “Creation Phase” before actually executing the code. This makes it appear as if declarations are magically moved to the top of the file, allowing you to call a function before you write it.

Mental Model

How It Works

Hoisting behaves differently depending on how you declare things:

  1. function Declarations: Fully hoisted. The entire function body is put into memory. You can call it anywhere.
  2. var Declarations: Partially hoisted. The variable name is put into memory, but it is initialized with the value undefined. The actual assignment (= 10) happens during the execution phase.
  3. let and const Declarations: Technically hoisted (the engine knows they exist), but they are placed in the Temporal Dead Zone (TDZ). You cannot access them before their actual line of code, resulting in a ReferenceError.
  4. Function Expressions (var a = function() {}): Behave like standard variables. The var name is hoisted as undefined, but the function itself is not available until the line executes.

Example

// 1. Function Declaration (Fully Hoisted)
sayHello(); // Output: "Hello!"
function sayHello() {
  console.log("Hello!");
}

// 2. var (Hoisted as undefined)
console.log(age); // Output: undefined
var age = 25;

// 3. let/const (Hoisted, but in TDZ)
// console.log(name); // ReferenceError!
let name = "Alice";

// 4. Function Expression (var rules apply)
// bark(); // TypeError: bark is not a function (it's undefined!)
var bark = function() {
    console.log("Woof");
}

Common Output Question

var myVar = "Global";

function scopeTest() {
  console.log(myVar);
  var myVar = "Local";
}

scopeTest();

Q: What does this output and why?
A: undefined.
When scopeTest runs, it creates a new Execution Context. Inside that context, the local var myVar is hoisted to the top of the function and initialized as undefined. When console.log(myVar) runs, it finds the local hoisted variable (undefined), overriding the global variable.

Senior Interview Question

Q: If let and const are hoisted, why do they throw an error instead of returning undefined like var?

A: TC39 (the JavaScript committee) intentionally designed let and const to remain uninitialized in the Temporal Dead Zone to catch bugs. var returning undefined silently caused millions of hard-to-track bugs where developers accidentally used variables before giving them values. By throwing a hard ReferenceError, modern JavaScript forces developers to write safer top-down code, catching logical initialization errors immediately at runtime.