Imagine a teacher who quickly checks the attendance list before class starts. The teacher notes who is present, then the class begins. JavaScript does something similar: before it runs your code it makes a short pass to note declarations. This behaviour is called hoisting.
Hoisting explains many surprises beginners see β like why var
sometimes gives undefined
, or why calling a function works even if the function appears later in the file. In this post we will explain hoisting in simple words, show clear code examples, and give short tips you can use right away.
π Why hoisting matters
When JavaScript runs a script it does two small steps for each scope (global or function):
- Creation step β it looks for declarations and prepares memory.
- Execution step β it runs the code line by line.
Hoisting happens because of that first step. If you know these two steps, many confusing behaviours become easy to understand.
β Easy intuition (no hard words)
- During the creation step,
var
names are set up and given the valueundefined
. -
let
andconst
names are known but not ready to use until the code reaches them β this waiting period is called the Temporal Dead Zone (TDZ). - Function declarations are ready in creation step with their full body, so you can call them even before the line where they are written.
π§ͺ Short examples (see it clearly)
1) var
example β gives undefined
console.log(a); // undefined
var a = 5;
console.log(a); // 5
What happened: JavaScript set up a
at the start (with value undefined
), then later the assignment a = 5
happened.
2) let
/ const
β not ready before their line
console.log(b); // ReferenceError
let b = 10;
What happened: b
is known to the engine, but it is not usable until the line let b = 10
runs. Accessing it early gives an error.
3) Function declaration β can be called early
greet(); // works: "Hello!"
function greet() {
console.log("Hello!");
}
What happened: The whole greet
function is set up during the creation step, so it is ready to call even before the code reaches its line.
4) Function expression β not hoisted the same way
sayHi(); // TypeError: sayHi is not a function
var sayHi = function() {
console.log("Hi");
};
What happened: sayHi
was set up as undefined
at creation. The function value is only assigned later. So calling it too early causes an error.
π Simple step-by-step of what engine does
-
Creation step: JavaScript finds declarations.
-
var
β create name, set toundefined
. -
let
/const
β reserve name, do not set a value yet (TDZ). - Function declarations β create name and set function value.
-
- Execution step: JavaScript runs the code line by line, doing assignments and calls.
This model is enough to reason about most hoisting cases.
β οΈ Common beginner mistakes (and quick fixes)
- Thinking hoisting moves code. It does not rewrite your source β it just prepares memory first. Fix: Read code top to bottom, initialise variables where you use them.
-
Using
var
everywhere.var
can causeundefined
surprises. Fix: Useconst
by default,let
when you must reassign. - Expecting function expressions to be callable early. Only function declarations are available before execution reaches them. Fix: Use function declarations when you need that behaviour, otherwise keep functions close to where they are used.
π Practical rules you can start using
- Prefer
const
for values that do not change,let
for values you will change. Avoidvar
. - Initialise variables near where you use them β it is clearer for readers and for you.
- If you need a helper that should be available anywhere in the scope, a function declaration is OK. Otherwise use function expressions for clearer order.
π― Bonus: How to explain hoisting in an interview (short and clear)
30-second answer:
Hoisting is the JS engineβs creation step that runs before code execution.
var
is hoisted and set toundefined
.let
andconst
are known but not usable until their line (TDZ). Function declarations are hoisted with their body.
Show quickly: paste this in the interview:
console.log(x); // undefined
var x = 1;
console.log(y); // ReferenceError
let y = 2;
foo(); // works
function foo() { console.log('hi') }
bar(); // TypeError
var bar = function() { console.log('ho') }
Common follow-ups: TDZ meaning, leading practice (const
/let
), and difference between function declarations and expressions.
π§ Key takeaways
- Hoisting = creation step + execution step.
-
var
β hoisted and initialised asundefined
. -
let
/const
β hoisted but not initialised (TDZ) until the line runs. - Function declarations β hoisted with the function body.
- Prefer
const
/let
and keep declarations clear and close to use.
π About Me
Hi, I'm Saurav Kumar β a Software Engineer building web and mobile apps using JavaScript, TypeScript, React, Next.js, and React Native.
I explore using AI tools to speed up development and I share beginner-friendly tutorials and practical tips.
π Connect with me:
If this helped you, please share with a friend learning JavaScript.
Until next time, keep coding and keep learning π
Top comments (0)