JavaScript Hoisting

Hoisting is one of JavaScript’s more confusing concepts for beginners, but once you understand it, it becomes a powerful tool in writing better and more predictable code. In simple terms, hoisting is JavaScript’s default behavior of moving declarations to the top of the current scope (script or function).

What is Hoisting?

In JavaScript, declarations (using var, let, const, and function declarations) are moved to the top of their containing scope during the compile phase — before the code is actually executed. This means you can use certain variables and functions before you declare them in your code, without getting an error (although the result may not be what you expect).

However, only the declarations are hoisted — not the initializations.


Variable Hoisting

Using var

javascriptCopyEditconsole.log(x); // undefined
var x = 10;
console.log(x); // 10

Why does the first console.log not throw an error? Because JavaScript reads it like this during compilation:

javascriptCopyEditvar x;         // declaration hoisted
console.log(x); // undefined
x = 10;        // initialization stays in place
console.log(x); // 10

So, var is hoisted and initialized to undefined until the actual assignment happens.

Using let and const

javascriptCopyEditconsole.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 5;

With let and const, the variable is also hoisted, but it remains in a “temporal dead zone” (TDZ) from the start of the block until the declaration is encountered. You cannot access it before it’s initialized.


Function Hoisting

Function Declarations

javascriptCopyEditsayHello(); // "Hello!"

function sayHello() {
  console.log("Hello!");
}

This works because function declarations are hoisted entirely, including their bodies.

Function Expressions

javascriptCopyEditsayHi(); // TypeError: sayHi is not a function

var sayHi = function() {
  console.log("Hi!");
};

Here, sayHi is hoisted like a variable declared with var, so JavaScript sees it as:

javascriptCopyEditvar sayHi;
sayHi(); // sayHi is undefined at this point
sayHi = function() {
  console.log("Hi!");
};

So, trying to call sayHi() before assignment results in a TypeError.


Best Practices for Hoisting

  1. Always declare variables at the top of their scope to avoid confusion.
  2. Use let and const instead of var to avoid unexpected hoisting behavior.
  3. Declare functions before you call them, especially if using function expressions.
  4. Avoid relying on hoisting in your code — while it works, it can make code harder to read and debug.

Summary

Declaration TypeHoisted?Initialized?Access Before Declaration
varYesundefinedAllowed, returns undefined
let / constYesNo (TDZ)ReferenceError
Function DeclarationYesYesAllowed
Function ExpressionYes (var)NoTypeError

Final Thought

JavaScript hoisting is like having the declarations “moved up” before your code runs, but it’s only the names that are lifted — not the values. Once you understand how this process works, you’ll find it much easier to debug tricky issues and write cleaner, more predictable code.

Leave a Reply

Your email address will not be published. Required fields are marked *