JavaScript Hoisting + Temporal Dead Zone (var vs let/const)
Interview-ready explanation of hoisting and the Temporal Dead Zone: what actually gets hoisted, why let/const behave differently, and common trick questions with outputs.
Frontend Interview Team
February 08, 2026
Hoisting is one of the most misunderstood JS topics because people explain it as:
“JavaScript moves declarations to the top.”
That’s not wrong, but it’s incomplete.
A better interview-friendly explanation:
During compilation, JS sets up memory for declarations. Then at runtime, code executes line by line.
30‑second interview answer
Hoisting is the JavaScript engine’s behavior of processing declarations before executing code. Function declarations are available before their line. var declarations are hoisted and initialized to undefined, while let/const are hoisted but live in the Temporal Dead Zone (TDZ) until their declaration is evaluated—accessing them early throws a ReferenceError.
Key points
- Function declarations: usable before they appear.
var: hoisted + initialized toundefined.let/const: hoisted + TDZ until initialization.- TDZ is about time (before initialization), not block position.
1) What gets hoisted?
✅ Function declarations (fully hoisted)
sayHi();
function sayHi() {
console.log('hi');
}Works because the function declaration is available before the call.
✅ var declarations (hoisted, initialized to undefined)
console.log(a); // undefined
var a = 10;
console.log(a); // 10What happens conceptually:
- declaration
var ais hoisted - initialization
a = 10stays where it is
⚠️ let / const declarations (hoisted, but in the TDZ)
console.log(x); // ReferenceError
let x = 10;They are hoisted but not initialized until the declaration is evaluated.
That time between entering the scope and reaching the declaration is the Temporal Dead Zone (TDZ).
2) TDZ in plain English
The TDZ means:
- the variable exists in the scope
- but you can’t access it yet
{
// TDZ starts here for `name`
// console.log(name); // ReferenceError
let name = 'Rajesh';
console.log(name); // Rajesh
// TDZ ends at the declaration line
}3) Common interview trick outputs
Example A
var a = 1;
(function () {
console.log(a);
var a = 2;
})();Output: undefined
Why: inside the IIFE, var a is hoisted to the top of that function scope, shadowing outer a.
Equivalent mental rewrite:
(function () {
var a;
console.log(a); // undefined
a = 2;
})();Example B
let a = 1;
{
// console.log(a); // ReferenceError
let a = 2;
}Why: the inner let a creates a new binding; before it’s initialized, accessing a hits the TDZ.
4) Function expressions vs function declarations
Function expression (behaves like var/let depending on declaration)
say(); // TypeError: say is not a function
var say = function () {
console.log('hi');
};var say is hoisted to undefined, so calling it gives TypeError.
With let
say(); // ReferenceError (TDZ)
let say = function () {};5) Interview answers (short + crisp)
Q: What is hoisting?
- JS allocates memory for declarations before execution.
Q: Why does var show undefined but let throws?
varis initialized toundefinedduring hoisting;let/constare in TDZ until initialized.
Q: Are let/const hoisted?
- Yes, but they’re not accessible before initialization.
Summary checklist
- I can explain hoisting as “declarations processed before execution”.
- I can explain why
varisundefinedbutletthrows. - I can define TDZ precisely.
- I know functions vs function expressions differ.
Summary
- Function declarations: usable before they appear.
var: hoisted + initialized toundefined.let/const: hoisted + TDZ until the declaration line.- Most interview bugs come from shadowing + assuming
varis block-scoped.