Open In App

JavaScript Hoisting

Last Updated : 11 Jul, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Hoisting refers to the behaviour where JavaScript moves the declarations of variables, functions, and classes to the top of their scope during the compilation phase. This can sometimes lead to surprising results, especially when using var, let, const, or function expressions.

  • Hoisting applies to variable and function declarations.
  • Initializations are not hoisted; they are only declarations.
  • 'var' variables are hoisted with undefined, while 'let' and 'const' are hoisted but remain in the Temporal Dead Zone until initialized.

Before going to learn more about Hoisting, it's important first to understand the Temporal Dead Zone

Temporal Dead Zone (TDZ)

The Temporal Dead Zone (TDZ) is a critical concept in JavaScript hoisting. It refers to the period between the entering of a scope (such as a function or block) and the actual initialization of a variable declared with let or const. During this time, any reference to the variable before its initialization will throw a ReferenceError.

How does the TDZ Work?

  • Variables declared with let and const are hoisted to the top of their scope, but they are not initialized until their declaration line is reached.
  • Any attempt to access these variables before their declaration will result in an error.
  • The TDZ exists only for variables declared using let and const. Variables declared with var do not have this issue, as they are hoisted and initialized to undefined.
index.js
hello(); // TypeError: hello is not a function
var hello = function() {
    console.log("Hi!");
};

Output

output
output


Note: The variable hello is hoisted, but it is not initialized until the assignment line is reached since it holds a function expression. Thus, calling hello() before its initialization throws a TypeError.

1. Variable Hoisting with var

When you use var to declare a variable, the declaration is hoisted to the top, but its value is not assigned until the code execution reaches the variable’s initialization. This results in the variable being assigned undefined during the hoisting phase.

index.html
console.log(a); // undefined
var a = 5;

Output

output
output


Note: The declaration var a is hoisted to the top, but a is initialized with undefined. Hence, logging results in undefined.

output
output

JavaScript's hoisting behavior with the var keyword, where the variable declaration (var b;) is moved to the top of its scope during the compilation phase, but its assignment (b = 2;) stays in place. As a result, the variable b is known to the interpreter from the beginning but is initially undefined until the assignment is executed. In the shown code, b is declared at the top (due to hoisting), then assigned 2, and finally displayed using alert, resulting in the output: b = 2.

Note: var hoisting lifts declarations, not initializations.

2. Variable Hoisting with let and const

Unlike var, let and const are also hoisted, but they remain in a Temporal Dead Zone (TDZ) from the start of the block until their declaration is encountered. Accessing them before their declaration will throw a ReferenceError.

JavaScript
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;

Output

output
output

Note: The variable is hoisted, but it’s in the Temporal Dead Zone (TDZ) until the declaration line is executed.

3. Function Declaration Hoisting

Function declarations are hoisted with both their name and the function body. This means the function can be called before its definition in the code.

index.js
greet(); // "Hello, Mahima!"
function greet() {
    console.log("Hello, Mahima!");
}
ouput
output



Note: The function declaration is hoisted, and the entire function definition is available before its position in the code.

4. Function Expression Hoisting

Function expressions are treated like variable declarations. The variable itself is hoisted, but the function expression is not assigned until the line of execution. This means calling the function before its assignment will result in an error.

index.js
hello(); // TypeError: hello is not a function
var hello = function() {
    console.log("Hi!");
};

Output

output
output


Note:The variable hello is hoisted, but since it's a function expression, it’s not initialized until the line is executed.

5. Hoisting with let and const in Functions

Variables declared with let and const inside a function are hoisted to the top of the function's scope, but they remain in the TDZ. This prevents access to them before they are initialized.

index.js
function test() {
    console.log(x); // ReferenceError: Cannot access 'x' before initialization
    let x = 50;
}
test();

Output

output
output


Note: The variable x is hoisted inside the function but cannot be accessed until its declaration line due to the TDZ.

6. Hoisting with Classes

Classes are hoisted, but they cannot be accessed before they are declared, resulting in a ReferenceError.

index.js
const obj = new MyClass(); // ReferenceError
class MyClass {
    constructor() {
        this.name = "Mahima Bhardwaj";
    }
}

Output:

output
ouput


Note: Although the class MyClass is hoisted, it cannot be accessed before its declaration due to the TDZ, which is why the code throws a ReferenceError.

7. Re-declaring Variables with var

With var, you can redeclare a variable within the same scope. This is a unique behavior compared to let and const.

index.js
var a = 10;
var a = 20; // No error
console.log(a); // 20

Output

output
output



Note: With var, the second declaration overwrites the first one without throwing an error.

8. Accessing Variables Declared Later in Loops

When using var in loops, the loop variable is hoisted to the function or global scope, which can cause unexpected behavior. If you use let, the variable is block-scoped and behaves as expected.

index.js
for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i); // 3, 3, 3
    }, 100);
}

Output

output
output

Note: The var i is hoisted, and all setTimeout functions share the same i reference, which results in the value 3 after the loop finishes.

9. Using Hoisted Functions with Parameters

Functions can be hoisted with their parameters, but any parameters passed to the function are still determined by the invocation, not by the hoisting.

index.js
test(10); // 10
function test(num) {
    console.log(num);
}

Output

output
output

Note : The entire function, including its parameters, is hoisted and available for use before the function's declaration in the code.

10. Hoisting in Nested Functions

Hoisting works within nested functions as well. Variables declared with var inside a function are hoisted to the top of that function scope.

index.js
function outer() {
    console.log(a); // undefined
    var a = 5;
    function inner() {
        console.log(b); // undefined
        var b = 10;
    }
    inner();
}
outer();

Output

output
output


Note: Both a and b are hoisted within their respective scopes (outer and inner functions), but their values are not set until the code execution reaches the initialization lines.


Hoisting - var & function
Video Thumbnail

Hoisting - var & function

Video Thumbnail

JavaScript Hoisting

Practice Tags :

Similar Reads