JavaScript Hoisting

1. Introduction to Hoisting

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their containing scope during the compile phase, before the code has been executed.

This means that no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.

2. Variable Hoisting (var)

Variables declared with var are hoisted to the top and initialized with undefined.

console.log(a);
var a = 10;
console.log(a);
        
Output will appear here...

3. let and const Hoisting

Variables declared with let and const are also hoisted, but they are not initialized. Accessing them before the declaration results in a ReferenceError.

This period between the start of the block and the declaration is known as the Temporal Dead Zone (TDZ).

try {
    console.log(b); // ReferenceError
} catch(e) {
    console.log(e.message);
}

let b = 20;
console.log(b);
        
Output will appear here...

4. Function Hoisting

Function Declarations are fully hoisted. You can call them before they are defined in the code.

hello();

function hello() {
    console.log("Hello World! I am hoisted.");
}
        
Output will appear here...

5. Function Expression Hoisting

Function Expressions (assigning a function to a variable) behave like variable hoisting. If you use var, it's undefined. If you use const, it's in the TDZ.

try {
    greet(); // TypeError: greet is not a function
} catch(e) {
    console.log(e.message);
}

var greet = function() {
    console.log("Hi");
};
        
Output will appear here...

6. Hoisting Comparison Table

Declaration Hoisted Initialized Value Access Before Declaration
var Yes undefined Returns undefined
let / const Yes Uninitialized (TDZ) Throws ReferenceError
Function Declaration Yes The Function Code Works Perfectly
Function Expression (var) Yes undefined Throws TypeError
Best Practice: Always declare variables and functions at the top of their scope to avoid confusion. Prefer let and const over var to avoid accidental hoisting bugs.

Practice Questions

Test your understanding of JavaScript Hoisting.

Easy

Q1: Predict the output of a hoisted var.

  • Write a document.write(score); statement.
  • On the next line, declare and initialize var score = 100;.
  • Explain the expected output in a comment.
Easy

Q2: Hoist a function declaration.

  • Call a function named sayHi().
  • Define the sayHi function after the function call to log "Hi!" to the console.
  • Observe how it works perfectly because function declarations are fully hoisted.
Medium

Q3: Observe let hoisting behavior.

  • Write a document.write(age); statement.
  • On the next line, declare and initialize let age = 25;.
  • Add a comment explaining the ReferenceError that is thrown.
Medium

Q4: Hoist a function expression.

  • Attempt to call foo() at the top of your script.
  • On the next line, declare a variable using var foo and assign an anonymous function to it.
  • Add a comment explaining why a TypeError occurs instead of a ReferenceError.
Hard

Q5: Demonstrate the Temporal Dead Zone (TDZ).

  • Create a block scope using curly braces {}.
  • Inside the block, comment out a document.write(x); statement that would cause a ReferenceError.
  • Below the log, declare let x = 10;.
  • Use comments to indicate where the TDZ starts and ends for the variable x.

Answer

Code: