If you've ever seen a JavaScript variable or function used before it's declared and somehow still work, you've already met hoisting.
Hoisting can be confusing at first, but once you understand the rules, it becomes a powerful concept that helps explain a lot of JavaScript’s behavior.
🧠 What is hoisting?
Hoisting is JavaScript's default behavior of moving declarations to the top of their scope before the code is executed.
In simpler terms:
JavaScript reads through your code first and "lifts" variable and function declarations to the top of their scope.
This doesn't mean your code literally moves—just that the engine _interprets_ it as if the declarations were at the top.
📦 Variable hoisting
Here’s a simple example:
console.log(a); // undefined
var a = 5;
Why doesn’t this throw an error?
Because JavaScript sees it like this:
var a;
console.log(a); // undefined
a = 5;
The declaration (var a
) is hoisted, but the assignment (= 5
) is not.
❌ Let and const are different
With let
and const
, declarations are also hoisted—but they're not initialized.
console.log(b); // ReferenceError
let b = 10;
This happens because of the Temporal Dead Zone—the time between the start of the block and the actual declaration. During this period, the variable exists but can’t be accessed.
So:
var
is hoisted and initialized withundefined
let
andconst
are hoisted but not initialized
🧩 Function hoisting
Function declarations are fully hoisted—including their body.
greet(); // "Hello!"
function greet() {
console.log("Hello!");
}
JavaScript moves the entire function definition to the top of the scope.
But be careful:
Function expressions are not hoisted the same way:
sayHi(); // TypeError: sayHi is not a function
var sayHi = function () {
console.log("Hi!");
};
In this case, sayHi
is hoisted as a var
, but it’s initialized with undefined
. So when you call it, it's not a function yet.
📚 Summary table
Type | Hoisted? | Initialized? | Can be used before declaration? |
var | Yes | Yes (undefined ) | Yes (but value is undefined ) |
let / const | Yes | No | No (ReferenceError) |
Function (declared) | Yes | Yes (full body) | Yes |
Function (expression) | Yes | As undefined | No (TypeError) |
✅ Recap
- ✅ JavaScript hoists declarations, not assignments
- ✅
var
variables are hoisted and initialized toundefined
- ✅
let
andconst
are hoisted but not initialized, and throw an error if accessed too early - ✅ Function declarations are hoisted completely
- ✅ Function expressions behave like
var
: hoisted but not initialized
📌 Conclusions
Hoisting can feel like magic, but it's just how JavaScript parses and prepares your code before running it.
Understanding hoisting helps you avoid bugs like using a variable before it's ready, or accidentally calling a function expression too soon.
If you ever wonder why something is undefined
or throwing a ReferenceError
, check if hoisting is the reason.