JavaScript Hoisting Interview Questions
One of the most common JavaScript interview questions is:
What is hoisting in JavaScript?
Most developers answer:
Variables and functions are moved to the top.
While this explanation works for beginners, it is not technically accurate.
Interviewers often ask deeper questions:
- Is code actually moved?
- Why does
varbehave differently fromletandconst? - What is the Temporal Dead Zone?
- How are functions hoisted?
- How does hoisting relate to execution contexts?
Let's understand hoisting from first principles.
1. What is Hoisting?
Hoisting is JavaScript's behavior of making declarations available before their actual position in the code during the creation phase of execution.
This allows code like:
console.log(name);
var name = "John";to execute without throwing a reference error.
Output:
undefinedThis surprises many developers.
The Common Misconception
Many tutorials explain hoisting as:
JavaScript moves code to the topExample:
console.log(name);
var name = "John";becomes:
var name;
console.log(name);
name = "John";This mental model helps beginners.
However:
JavaScript does NOT physically move code.Instead, hoisting happens during execution context creation.
2. Under the Hood: Execution Context
Before JavaScript executes code, it creates an:
Execution ContextThis process has two phases:
1. Creation Phase
2. Execution PhaseCreation Phase
JavaScript scans the code and registers:
- Variables
- Functions
- Parameters
Memory is allocated.
Execution Phase
JavaScript executes code line by line.
Visual Representation
Creation Phase
↓
Allocate Memory
↓
Execution Phase
↓
Run CodeHoisting occurs during:
Creation Phase3. Variable Hoisting with var
Example:
console.log(name);
var name = "John";During creation phase:
name = undefined;During execution:
console.log(name);Output:
undefinedThen:
name = "John";Why Doesn't It Throw an Error?
Because:
var name;already exists in memory.
Its initial value is:
undefined;Visual Example
Code:
console.log(name);
var name = "John";Creation Phase:
name = undefined;Execution Phase:
console.log(undefined);
name = "John";Output:
undefined4. Function Hoisting & Declaration vs. Expression
Function declarations are fully hoisted.
Example:
greet();
function greet() {
console.log("Hello");
}Output:
HelloWhy?
Because the entire function is stored during creation.
Creation phase:
greet = function () {
console.log("Hello");
};Function Declaration vs Function Expression
Interviewers love this question.
Example:
greet();
var greet = function () {
console.log("Hello");
};Output:
TypeErrorWhy?
Creation phase:
greet = undefined;Execution:
greet();Equivalent to:
undefined();Which causes:
TypeError: greet is not a functionFunction Declaration Example
greet();
function greet() {
console.log("Hello");
}Output:
HelloBecause the entire function is hoisted.
Function Expression Example
greet();
const greet = function () {
console.log("Hello");
};Output:
ReferenceErrorThis leads us to:
let and const5. Block Scope Hoisting: let and const
Many developers believe:
let is not hoistedThis is incorrect.
Example:
console.log(age);
let age = 25;Output:
ReferenceErrorIs let Hoisted?
Yes.
During creation phase:
age;is registered.
However:
It remains uninitialized.This creates the:
Temporal Dead Zone (TDZ)6. The Temporal Dead Zone (TDZ)
The Temporal Dead Zone is the period between:
Variable Creation
and
Variable InitializationExample:
console.log(age);
let age = 25;Timeline:
Creation Phase
↓
age exists
Execution Begins
↓
TDZ
let age = 25
↓
InitializedAccessing it during TDZ causes:
ReferenceErrorHoisting with const
const behaves similarly to let.
Example:
console.log(PI);
const PI = 3.14;Output:
ReferenceErrorReason:
Temporal Dead Zone7. Side-by-Side Comparison: var vs. let vs. const
Consider:
console.log(a);
console.log(b);
console.log(c);
var a = 1;
let b = 2;
const c = 3;Output:
undefined
ReferenceError
ReferenceErrorComparison Table
| Declaration | Hoisted | Initialized |
|---|---|---|
| var | ✅ Yes | ✅ undefined |
| let | ✅ Yes | ❌ No |
| const | ✅ Yes | ❌ No |
| function declaration | ✅ Yes | ✅ Function |
| function expression | Depends on variable declaration | Depends on variable declaration |
Interview Question
What is the output?
var x = 1;
function test() {
console.log(x);
var x = 2;
}
test();Answer
Output:
undefinedWhy?
Creation phase inside function:
var x = undefined;Execution:
console.log(x);Output:
undefinedThen:
x = 2;Another Interview Question
What is the output?
let x = 1;
function test() {
console.log(x);
let x = 2;
}
test();Answer
Output:
ReferenceErrorBecause:
x;is inside the TDZ.
Nested Scope Example
var name = "Global";
function demo() {
console.log(name);
var name = "Local";
}
demo();Output:
undefinedLocal variable hoisting shadows the global variable.
8. Class Hoisting Rules
Classes are also hoisted.
Example:
const user = new User();
class User {}Output:
ReferenceErrorWhy?
Classes behave similarly to:
let;They exist in a Temporal Dead Zone until initialized.
9. Common Interview Q&A
Is JavaScript Moving Code to the Top?
No.
JavaScript creates bindings during the creation phase of execution contexts.
Are let and const Hoisted?
Yes.
They are hoisted but remain uninitialized until execution reaches their declaration.
What Causes the Temporal Dead Zone?
Accessing a hoisted variable before it has been initialized.
Why Does var Return Undefined?
Because var is initialized with:
undefined;during the creation phase.
Why Are Function Declarations Callable Before Definition?
Because the entire function is stored in memory during the creation phase.
Real Frontend Example
Consider:
function initializeApp() {
loadUser();
}
function loadUser() {
console.log("Loading user...");
}
initializeApp();This works because function declarations are hoisted.
Senior-Level Interview Answer
Hoisting is JavaScript's behavior of creating bindings for variables and functions during the creation phase of an execution context before code execution begins. Variable declarations using
varare hoisted and initialized withundefined, whileletandconstare hoisted but remain uninitialized inside the Temporal Dead Zone until their declaration is evaluated. Function declarations are fully hoisted, allowing them to be invoked before their definition appears in the source code. Hoisting is not the physical movement of code but a consequence of how JavaScript builds execution contexts.
Common Interview Mistakes
❌ "JavaScript moves code to the top."
Correct:
JavaScript creates bindings during
the creation phase.❌ "let and const are not hoisted."
Correct:
They are hoisted but remain
uninitialized.❌ "Function expressions are hoisted like functions."
Correct:
Only the variable declaration is hoisted.❌ "TDZ means the variable doesn't exist."
Correct:
The variable exists but cannot
be accessed yet.Hoisting Summary
| Feature | var | let | const |
|---|---|---|---|
| Hoisted | ✅ | ✅ | ✅ |
| Initialized During Creation | ✅ undefined | ❌ | ❌ |
| Temporal Dead Zone | ❌ | ✅ | ✅ |
| Reassignment Allowed | ✅ | ✅ | ❌ |
Key Takeaways
- Hoisting Myth: JavaScript does not move code lines; the compiler registers variables and functions during the creation phase.
- var Sizing: Declaring variables with
varinitializes them asundefined, avoiding compile-time ReferenceErrors. - let & const TDZ: Block-scoped variables are hoisted but reside in the Temporal Dead Zone (TDZ) until their declaration line is evaluated.
- Functions: Function declarations are hoisted fully, making them callable before definition; function expressions are not.