Hoisting is one of those JavaScript concepts that can cause surprising behavior if you’re not aware of how it works. Yet, once you understand it, you’ll write more predictable and bug-free code. In this blog post, we’ll demystify what hoisting is, how it affects variables and functions, and the differences between var
, let
, const
, and function expressions.
Hoisting is JavaScript’s behavior of moving declarations to the top of their scope before code is executed.
For example:
console.log(x); // undefinedvar x = 10;
Behind the scenes, JavaScript interprets this as:
var x;console.log(x); // undefinedx = 10;
Only the declaration is hoisted, not the initialization.
var
vs let
/ const
var
— Hoisted and Initialized as undefined
console.log(a); // undefinedvar a = 5;
var
variables are hoisted to the top of their function scope and initialized to undefined
.
let
/ const
— Hoisted but in the Temporal Dead Zone (TDZ)console.log(b); // ❌ ReferenceErrorlet b = 10;
console.log(c); // ❌ ReferenceErrorconst c = 20;
Although let
and const
are hoisted, they are not initialized. Accessing them before declaration results in a ReferenceError due to the temporal dead zone (TDZ).
sayHello(); // "Hello"function sayHello() {console.log("Hello");}
Function declarations are hoisted with their definitions, so you can safely call them before they appear in your code.
greet(); // ❌ TypeError: greet is not a functionvar greet = function () {console.log("Hi");};
Here, only the var greet
declaration is hoisted and initialized as undefined
. Trying to call greet()
before the assignment causes a TypeError.
shout(); // ❌ TypeErrorconst shout = () => console.log("Shout!");
With const
and arrow functions, the variable is hoisted but uninitialized (TDZ), so accessing it early throws a ReferenceError.
Declaration Type | Hoisted? | Initialized? | Usable Before Declaration? |
---|---|---|---|
var | ✅ Yes | ✅ As undefined | ⚠️ Yes, but risky |
let / const | ✅ Yes | ❌ No (TDZ) | ❌ No |
Function Declaration | ✅ Yes | ✅ Yes | ✅ Yes |
Function Expression | ✅ (var) | ❌ No | ❌ No |
Arrow Function | ✅ (var) | ❌ No | ❌ No |
let
and const
over var
to avoid unexpected hoisting behavior.const
by default, and let
when reassignment is necessary.Hoisting is a foundational concept in JavaScript that influences how your code is parsed and executed. Understanding how variable and function declarations are treated helps you write cleaner, more reliable code. By steering clear of var
and being mindful of declaration order, you can avoid many common JavaScript pitfalls.
Stay tuned for our next post, where we’ll explore how closures interact with hoisting and function scopes!
Quick Links
Legal Stuff
Social Media