TL;DR
- JavaScript hoisting means that variable and function declarations are moved to the top of their scope before execution.
- Only declarations are hoisted, not initializations.
- Function declarations are hoisted entirely, but function expressions are not.
- Using
let
andconst
prevents unexpected hoisting behaviors. - Avoid relying on hoisting and write clean, predictable code.
JavaScript hoisting is one of those concepts that confuses developers—especially beginners. Many assume that JavaScript moves declarations to the top, but the reality is a bit more nuanced. If not understood correctly, hoisting can lead to unexpected errors and hard-to-debug issues.
In this article, we will break down hoisting, explain how variables and functions behave, highlight common mistakes, and provide best practices to avoid pitfalls.
What is Hoisting in JavaScript?
Hoisting is JavaScript’s behavior of moving variable and function declarations to the top of their scope before execution.
This means you can use variables and functions before declaring them in your code but with some important caveats.
Example of Hoisting:
console.log(x); // Output: undefined
var x = 5;
console.log(x); // Output: 5
You might expect the first console.log(x);
to throw an error because x
is declared after it, but JavaScript hoists the declaration of x
to the top:
var x;
console.log(x); // undefined
x = 5;
console.log(x); // 5
While declarations are hoisted, assignments are not.

How Javascript Hoisting Works with Variables
var
Hoisting
Variables declared with var
are hoisted to the top of their function or global scope but are initialized with undefined
.
Example:
console.log(name); // Output: undefined
var name = "John";
console.log(name); // Output: "John"
Behind the scenes, JavaScript rearranges the code like this:
var name;
console.log(name); // undefined
name = "John";
console.log(name); // "John"
let
and const
Hoisting (Why They Are Different)
Variables declared with let
and const
are hoisted but do not get initialized. This results in a “Temporal Dead Zone” (TDZ) error if accessed before declaration.
Example:
console.log(age); // ReferenceError: Cannot access 'age' before initialization
let age = 30;
In contrast to var
, JavaScript does not initialize let
and const
variables with undefined
. Instead, they are in a temporal dead zone from the start of the block until the declaration is encountered.
const
Hoisting Rules
const
behaves like let
but must be assigned a value at declaration:
console.log(pi); // ReferenceError
const pi = 3.14;
How Hoisting Works with Functions
Function Declarations are Fully Hoisted
Unlike variables, function declarations are hoisted with their full implementation.
Example:
greet(); // Output: "Hello, world!"
function greet() {
console.log("Hello, world!");
}
Behind the scenes:
function greet() {
console.log("Hello, world!");
}
greet(); // "Hello, world!"
This means you can call function declarations before defining them.
Function Expressions Are NOT Hoisted
A function expression assigned to a variable behaves differently because only the variable declaration is hoisted, not the function itself.
Example:
sayHi(); // TypeError: sayHi is not a function
var sayHi = function() {
console.log("Hi!");
};
What happens behind the scenes:
var sayHi;
sayHi(); // Error: sayHi is not a function
sayHi = function() {
console.log("Hi!");
};
Common Mistakes Due to Hoisting
Hoisting can lead to unexpected errors if not handled properly.
Mistake 1: Using var
Before Assignment
console.log(user); // undefined
var user = "Alice";
console.log(user); // Alice
Best Practice: Always declare variables before using them.
Mistake 2: Assuming let
and const
Behave Like var
console.log(score); // ReferenceError
let score = 10;
Best Practice: Use let
and const
to avoid unexpected hoisting issues.
Mistake 3: Using Function Expressions Before Initialization
callMe(); // TypeError: callMe is not a function
var callMe = function() {
console.log("Calling...");
};
Best Practice: Use function declarations if you need to call them before definition.
Best Practices for Avoiding Hoisting Issues
Declare Variables at the Top of Their Scope
function example() {
let name;
console.log(name); // undefined
name = "Alice";
}
Use const
and let
Instead of var
let age = 25;
const PI = 3.14;
Use Function Declarations When Possible
function add(a, b) {
return a + b;
}
Avoid Function Expressions Before Declaration
const greet = function() {
console.log("Hello!");
};
greet();
FAQs
What is hoisting in JavaScript?
- Hoisting is JavaScript’s behavior of moving variable and function declarations to the top of their scope before execution.
Are let
and const
hoisted?
- Yes, but they remain in the Temporal Dead Zone (TDZ) until their declaration is reached.
What is the difference between function declarations and function expressions in hoisting?
- Function declarations are hoisted completely.
- Function expressions are not hoisted (only their variable declaration is hoisted).
How do I avoid hoisting issues?
- Declare variables at the top.
- Use
let
andconst
. - Use function declarations when needed before execution.