Hoisting
Why You Can Use Variables Before You Declare Them
LinkedIn Hook
console.log(x)beforevar x = 10printsundefined. The same pattern withlet x = 10throws a ReferenceError. Why?The answer is hoisting — and almost every tutorial explains it wrong. Nothing physically moves to the top of your file. The JS engine simply allocates memory for declarations during the Creation Phase, BEFORE executing a single line of code.
Function declarations get fully stored (body and all), which is why you can call them before they appear.
vargets initialized toundefined.letandconstget hoisted but locked in the Temporal Dead Zone.In this lesson you'll see exactly what gets hoisted, how much of it is hoisted, and the classic trick question —
var myFunc = "hello"vsfunction myFunc() {}— that trips up even senior devs.If you've ever been asked "explain hoisting" in an interview and your answer was "it moves variables to the top" — this lesson rewrites that answer.
Read the full lesson -> [link]
#JavaScript #InterviewPrep #Hoisting #JSEngine #VarLetConst #Frontend #CodingInterview
What You'll Learn
- What hoisting actually is (hint: nothing moves)
- What gets hoisted and what value it starts with for each declaration type
- Why function declarations can be called before they appear, but function expressions can't
- The function-vs-variable hoisting precedence trap
What Hoisting Really Is
Hoisting is JavaScript's behavior of moving declarations (not assignments) to the top of their scope during the Creation Phase.
But here's the important part: nothing physically moves. The JS engine just allocates memory for declarations before executing any code.
What Gets Hoisted and How?
| Declaration | Hoisted? | Initial Value |
|---|---|---|
var x = 5 | Yes | undefined |
let x = 5 | Yes (but in TDZ) | uninitialized |
const x = 5 | Yes (but in TDZ) | uninitialized |
function greet() {} | Yes | Full function body |
var greet = function() {} | Yes (var only) | undefined |
var greet = () => {} | Yes (var only) | undefined |
Code Example — Variable Hoisting
console.log(a); // undefined (not ReferenceError!)
console.log(b); // ReferenceError: Cannot access 'b' before initialization
console.log(c); // ReferenceError: Cannot access 'c' before initialization
var a = 10;
let b = 20;
const c = 30;
What the engine sees (conceptually):
var a = undefined; // hoisted with default value
// let b -> exists in memory but in TDZ (no default)
// const c -> exists in memory but in TDZ (no default)
console.log(a); // undefined
console.log(b); // ReferenceError (TDZ)
console.log(c); // ReferenceError (TDZ)
a = 10;
b = 20;
c = 30;
Code Example — Function Hoisting
// This works! Function declarations are fully hoisted
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
// This BREAKS! Function expressions are NOT fully hoisted
sayBye(); // TypeError: sayBye is not a function
var sayBye = function () {
console.log("Bye!");
};
Why does sayBye fail? Because var sayBye is hoisted as undefined. Calling undefined() throws a TypeError.
Tricky Example — Functions vs Variables
var myFunc = "hello";
function myFunc() {
return "world";
}
console.log(typeof myFunc); // "string"
Why? During creation phase, both are hoisted. But in the execution phase, var myFunc = "hello" reassigns it to the string. Function declarations are hoisted first, then variable assignments overwrite them.
Common Mistakes
- Saying "hoisting physically moves declarations to the top" — it doesn't; memory is allocated in a separate phase, nothing in your source file actually moves.
- Thinking
letandconstare NOT hoisted — they are, they're just kept in the TDZ until their declaration line is reached. - Calling a function assigned to a
varbefore its assignment line and expecting it to work — only function declarations (thefunction foo() {}form) are fully hoisted; function expressions (var foo = function() {}) leavefooasundefineduntil the assignment runs.
Interview Questions
Q: What is hoisting in JavaScript?
Hoisting is the engine's Creation-Phase behavior of allocating memory for declarations before executing any code.
varis initialized toundefined,let/constare left uninitialized in the TDZ, and function declarations are stored with their full body.
Q: Are let and const hoisted?
Yes, they are hoisted — but they're placed in the Temporal Dead Zone (TDZ) from the start of the block until the declaration line. Accessing them before declaration throws a ReferenceError, not undefined like
var.
Q: What's the difference between hoisting of function declarations vs function expressions?
Function declarations (
function foo() {}) are hoisted with their entire body, so they're callable before the line they appear on. Function expressions (var foo = function() {}) only hoist thevarbinding asundefined; callingfoo()before the assignment throwsTypeError: foo is not a function.
Q: What will console.log(x) output if var x = 5 is declared later?
undefined. Thevar xdeclaration is hoisted and initialized toundefined, but the assignmentx = 5stays in its original position.
Q: Does hoisting physically move code?
No. It's a conceptual description of what happens in the Creation Phase — memory is allocated for declarations, but the source text itself is unchanged.
Quick Reference — Cheat Sheet
HOISTING — WHAT GETS HOISTED AND HOW
Declaration | Hoisted | Initial Value
-------------------------|---------|---------------------
var x = 5 | yes | undefined
let x = 5 | yes | uninitialized (TDZ)
const x = 5 | yes | uninitialized (TDZ)
function f() {} | yes | full function body
var f = function () {} | yes | undefined
var f = () => {} | yes | undefined
Precedence inside the same scope:
function declarations hoist FIRST
var assignments then run and can overwrite them
Previous: Call Stack Next: Temporal Dead Zone
This is Lesson 1.3 of the JavaScript Interview Prep Course — 14 chapters, 87 lessons.