Intermediate · Scope, this, prototypes and classes · topic 21 of 61 · 25 min
Hoisting and the temporal dead zone
Explanation
Two phases: creation and execution
When a script or a function starts, the engine does not just read line by line. First, in the creation phase, it finds every declaration in that scope and sets up the names. Then, in the execution phase, it runs the code from the top. The effect is as if declarations were "hoisted" (lifted) to the top of their scope. Nothing actually moves in your file; it is a way of describing this two-step process.
Function declarations are fully hoisted
console.log(add(2, 3)); // 5: works before the definition
function add(a, b) {
return a + b;
}var is hoisted as undefined
console.log(price); // undefined (no error!)
var price = 499;
console.log(price); // 499This silent undefined is why var bugs are hard to find: the program keeps running with a wrong value instead of stopping with a clear error.
let, const and class: the temporal dead zone
let, const and class are also hoisted (the engine knows the names), but they are not initialised. From the start of the block until the declaration line runs, the variable is in the temporal dead zone (TDZ). Touching it there throws a ReferenceError. This is GOOD: a loud error is better than a silent undefined.
console.log(total); // ReferenceError: Cannot access 'total' before initialization
let total = 100;let city = 'Pune';
function show() {
console.log(city); // ReferenceError, not 'Pune'!
let city = 'Goa'; // this inner city is hoisted to the top of show()
}
show();Function expressions and arrows are not callable early
greet(); // TypeError: greet is not a function (with var)
var greet = function () { console.log('hi'); };
wave(); // ReferenceError (with const: TDZ)
const wave = () => console.log('bye');| Declaration | Hoisted? | Value before its line |
|---|---|---|
| function f() {} | Yes, fully | The working function |
| var x | Yes | undefined |
| let x / const x | Yes, but in the TDZ | ReferenceError if used |
| class C {} | Yes, but in the TDZ | ReferenceError if used |
| var f = function () {} | Only the name f | undefined, so calling it is a TypeError |
Execution context and the call stack
Each time a function is called, the engine creates an execution context: a record holding that call's variables, its this value and a link to the outer scope. Contexts are pushed onto the call stack and popped off when the function returns. Hoisting happens at the creation of each context.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Hoisting and the temporal dead zone · 1/6
In this lesson you will learn what happens before your code runs, which is called hoisting.
Prefer a video by a teacher? Find free videos on “javascript hoisting temporal dead zone explained” on YouTube ↗
In real life: A crash that var would have hidden
In a payroll script, a developer used the bonus variable before calculating it. With var, salaries were silently computed with bonus = undefined, giving NaN in every payslip that went to the bank file. With let, the script would have stopped at once with a ReferenceError pointing to the exact line.
function netPay(basic) {
const pay = basic + bonus; // ReferenceError with let: caught in testing
let bonus = basic * 0.1;
return pay;
}
try { netPay(30000); } catch (e) { console.log(e.name); } // ReferenceErrorPractice (0/2 done)
This code calls getTax before it is defined and crashes, because getTax is a const arrow function. Change ONLY the definition into a function declaration so the call works.
Write whatHappens(kind) that returns what you get when you read a variable BEFORE its declaration line: for "var" return "undefined", for "let" and "const" return "ReferenceError", for "function" return "works". Anything else returns "unknown".
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- How this worksScope, this, prototypes and classes · same module
- Prototypes and the prototype chainScope, this, prototypes and classes · same module
- ClassesScope, this, prototypes and classes · same module
- Scope, hoisting and closuresFrontend Web Development · JavaScript in depth
- Predict-the-output questionsInterview preparation and career
- FunctionsFrontend Web Development · JavaScript basics
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
console.log(a); var a = 3; What is printed?
Answer: undefined
var is hoisted and initialised with undefined.
console.log(b); let b = 3; What happens?
Answer: ReferenceError
b is in the temporal dead zone until its declaration runs.
sayHi(); function sayHi() { return "hi"; } Does the call work?
Answer: Yes
Function declarations are fully hoisted.
f(); var f = () => 1; What happens?
Answer: TypeError: f is not a function
f exists as undefined, and calling undefined is a TypeError.
Why can you call a function declaration above the line where it is written?Related
Answer: Hoisting: function declarations are ready before the code runs
JavaScript notes declarations before running. Function declarations are fully hoisted, unlike let and const.
function f() { return 1; console.log("hi"); } What happens when f() runs?Related
Answer: Returns 1 and never prints
return ends the function; the next line is never reached.
if (true) { let a = 1; } console.log(a); What happens?Related
Answer: ReferenceError
let is block-scoped, so a does not exist outside the braces.
const a = [1, 2, 3]; a[10] = 4; console.log(a.length) prints…Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 4 more topics in “Scope, this, prototypes and classes” before its exam: How this works, Prototypes and the prototype chain, Classes, Inheritance and composition.
- Module 5 exam: Scope, this, prototypes and classes · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Modules, errors, JSON and dates. 61 topics left in the course before the final exam.