Skip to main content

Command Palette

Search for a command to run...

Hoisting in JavaScript

Updated
4 min readView as Markdown

Hoisting

JavaScript behaves differently from many other programming languages.
One of its unique behaviors is called hoisting.

Hoisting affects how variables and functions are created.
It can confuse beginners, and even experienced developers sometimes forget how it works.

In this article, you will learn:

  • what hoisting means

  • how variable hoisting works

  • how function hoisting works

  • common mistakes

  • the “correct mental model” to avoid bugs

Let’s start with the definition.


What Is Hoisting?

Hoisting means JavaScript moves variable and function declarations to the top of their scope before code runs.

This does not mean your code is rearranged.
It means JavaScript creates memory for these declarations during the “creation phase” of execution.

So you can use some variables and functions even before they appear in your code.


Function Hoisting

Function declarations are fully hoisted.

This means you can call the function before you write it.

Example:

sayHello(); // Output: Hello!

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

This works because during hoisting, JavaScript stores the entire function in memory.

When is this useful?

  • It allows you to write code in any order.

  • You can place helper functions at bottom and main logic at the top.


Variable Hoisting

Variables behave differently depending on whether you use:

  • var

  • let

  • const

Let’s look at each one.


1. Hoisting with var

Variables declared with var are hoisted but initialized with undefined.

Example:

console.log(a); // undefined
var a = 10;

The variable exists at the top of the scope, but it does not have a value yet.


2. Hoisting with let and const

let and const are also hoisted, but they are not initialized.

They are placed in something called the Temporal Dead Zone (TDZ) until the line where they are declared.

Example:

console.log(x); //  ReferenceError
let x = 5;

Why the error?

Because x exists, but JavaScript does not allow you to use it before declaration.

Same with const:

console.log(y); //  ReferenceError
const y = 20;

The Temporal Dead Zone (TDZ)

The TDZ is the region from the start of the scope to the line where the variable is declared.

You cannot access the variable in this zone.


Correct Mental Model for Hoisting

Think of hoisting like this:

During the Memory Creation Phase:

  • Function declarations → stored as full functions

  • var → stored as undefined

  • let and const → allocated but not initialized (TDZ)

During the Execution Phase:

  • Code runs line by line

  • Values are assigned

  • TDZ ends at the declaration line


Function Declaration vs Function Expression

Hoisting behaves differently depending on the syntax.


1. Function Declarations (fully hoisted)

greet(); // Works!

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

2. Function Expressions (NOT fully hoisted)

Using var:

greet(); // TypeError: greet is not a function

var greet = function () {
  console.log("Hello!");
};

Why?

var greet becomes undefined during hoisting.
So at the time of the call, greet is undefined, not a function.


3. Arrow Functions

Arrow functions behave like function expressions.

Using let:

greet(); // ReferenceError

let greet = () => {
  console.log("Hello!");
};

They stay in the Temporal Dead Zone until declared.


Common Mistakes with Hoisting

Mistake 1: Using variables before declaring them

console.log(score); // ReferenceError
let score = 100;

Mistake 2: Assuming var is safe because it does not throw error

console.log(a); // undefined, not error
var a = 1;

This often causes silent bugs.

Mistake 3: Assuming all functions are hoisted the same way

run(); //  Error

let run = function () {};

Function expressions are not hoisted like declarations.


Best Practices to Avoid Hoisting Bugs

✔ Always declare variables at the top of the scope
✔ Use let and const instead of var
✔ Write functions before calling them (even though not required)
✔ Avoid mixing declarations and usage in confusing order
✔ Use const for functions when possible

These practices make your code predictable and easier to read.


Summary

ItemHoisted?Initialized?Usable before declaration?
varYesundefinedYes (but unsafe)
letYesNo (TDZ)No
constYesNo (TDZ)No
Function DeclarationYesYes (full function)Yes
Function ExpressionYes (variable only)NoNo
Arrow FunctionYes (variable only)NoNoHoisting in JavaScript: A Simple Guide for Beginners

More from this blog

Javascript Beginner Articles

23 posts