What is Hoisting?
Hoisting is a behavior in JavaScript where variable and function declarations are moved to the top of their containing scope during the compile phase. This allows you to use variables and functions before they are declared in the code.
To put it simply, JavaScript “hoists” declarations, not initializations.
How Does Hoisting Work?
In JavaScript, the interpreter splits code into two phases:
- Compilation Phase: During this phase, JavaScript scans the code for variable and function declarations and allocates memory for them.
- Execution Phase: This is when the actual execution of the code takes place.
When a variable or function is declared, JavaScript moves its declaration to the top of its scope during the compilation phase. However, the initialization (if any) remains in its original place.
Example of Variable Hoisting
console.log(myVar); // Output: undefined
var myVar = 10;
console.log(myVar); // Output: 10Here, the declaration var myVar is hoisted to the top, but the initialization (myVar = 10) is not. Thus, myVar is undefined before it is assigned a value.
Example of Function Hoisting
sayHello(); // Output: Hello, World!
function sayHello() {
console.log("Hello, World!");
}Function declarations are fully hoisted, meaning you can call them before they appear in the code.
Function Expressions & Arrow Functions
- Not hoisted like declarations.
- They behave like variables; if declared with
var, they are hoisted withundefined.
greet(); // TypeError
var greet = function() {
console.log("Hello");
};❌ Function Expressions Are Not Hoisted
With function expressions, only the variable declaration is hoisted — not the function value assigned to it. So if you try to call the function before the line where it’s defined, it either throws a TypeError or behaves unexpectedly.
Example with var:
sayHi(); // ❌ TypeError: sayHi is not a function
var sayHi = function() {
console.log("Hi!");
};var sayHiis hoisted and initialized toundefined.- The function assignment happens later, so calling it early fails.
Example with let or const:
sayHi(); // ❌ ReferenceError
const sayHi = function() {
console.log("Hi!");
};sayHiis in the Temporal Dead Zone (TDZ) and cannot be accessed before the declaration.
What About let and const?
Variables declared with let and const are also hoisted, but they are not initialized. Accessing them before their declaration results in a ReferenceError. This is because they are in a “temporal dead zone” from the start of the block until the declaration is encountered.
console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization
let myLet = 20;Summary:
| Type | Hoisted? | Callable Before Definition? | Notes |
|---|---|---|---|
function declaration | ✅ Yes | ✅ Yes | Fully hoisted with body |
function expression | ⚠️ Partially | ❌ No | Only variable is hoisted (value isn’t) |
arrow function | ⚠️ Partially | ❌ No | Behaves like a function expression |
Key Takeaways
- Hoisting moves declarations to the top of their scope during compilation.
- Variable initializations are not hoisted.
- Function declarations are fully hoisted,function expressions are not.
- Variables declared with
letandconstare in a temporal dead zone until initialized.
