Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
All about Variables  ›  Capstone Project

Hoisting

Hoisting 12 minBefore code runs, declared names are registered: function declarations with their body, var as undefined, and let and const locked until their line.

Hoisting

In short: before any code in a scope runs, the engine scans it and registers every declared name — this is called hoisting. What a name holds before its own line runs depends on how it was declared: a function declaration is hoisted with its whole body, so it can be called early. var is hoisted as undefined. let and const are hoisted but locked — reading them before their line throws. That locked stretch, from the start of the scope to the declaration's line, is called the temporal dead zone.

Two columns: written order on the left (start(); console.log(volume); console.log(title); function start(){...} var volume = 80; let title = "Blue Hour";) with arrows lifting the function and var up to a "registered before line 1" board on the right showing start → the whole function (runs early), volume → undefined (real value waits for its line), title → locked, dead zone (reading it early throws ReferenceError)

Call a function before its declaration

Function declarations are hoisted whole, body included, so calling one "early" works exactly as if it had already been defined:

javascript

This prints hi. The engine registered the entire greet function before line 1 ran, so by the time greet() executes, there is a real function behind the name.

Read a var before its line, then a let

var is hoisted too, but only as undefined — the real value arrives when its line runs. let is hoisted locked, in the temporal dead zone:

javascript

This prints undefined, not an error — the name existed early, just without its value yet. Do the same with let:

javascript

This throws a ReferenceError before printing anything. title is registered, but locked, until the line that declares it runs. Even typeof title on the line above would throw — being in the dead zone gives no protection.

A function stored in a var, called too early

This is where the two rules collide, and where the two different errors matter. A function assigned to a var is not the same as a function declaration:

javascript

This throws TypeError: play is not a function — not a ReferenceError. play exists early (hoisted as var), but it holds undefined until its assignment line runs, and calling undefined as a function is a TypeError. Written as function play() { ... } instead, the whole function would be registered from the start, and calling it early would print go.

A ReferenceError means the name cannot be used yet, or does not exist at all. A TypeError means the name exists but holds the wrong kind of value. The simple habit that avoids both: declare before you use.

Tracing a function stored in a varStep 1 of 4
  1. The code

    play(); var play = function () { console.log("go"); };

Quick practice

quick drill

What does console.log(x); var x = 5; log?

quick drill

What does console.log(y); let y = 5; do?

quick drill

What does greet(); function greet() { console.log("hi"); } do?

quick drill

What does play(); var play = function () { console.log("go"); }; do?

quick drill

What does let a = 1; { console.log(a); let a = 2; } do?

🎯 Your turn

Predict and explain the output of: console.log(a); console.log(typeof b); console.log(c()); var a = 1; let b = 2; function c() { return 3; }

Write your explanation and submit it — there's no code to run here, just your reasoning.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainPredict before it runs

Predict and explain the output of: console.log(a); console.log(typeof b); console.log(c()); var a = 1; let b = 2; function c() { return 3; }