JavaScript Hoisting: How It Works with Examples

javascript hoisting with examples

You will face hoisting early when you write JavaScript. It affects how your code runs, and it may confuse you if you do not expect it. In this guide, you will understand hoisting in detail, from the basics to how it works under the hood with examples.

Understand Hoisting in JavaScript

Hoisting means JavaScript moves variable and function declarations to the top of their scope during the compile phase.

This happens before the code runs. JavaScript does not move the values, only the declarations. That is why you may use a variable before you define it—sometimes.

Many new developers get stuck when a variable looks like it should be undefined but has a value. Or when they call a function before they define it, and it works.

These cases come from hoisting. If you understand it, you avoid bugs and write clearer code.

var declarations get hoisted to the top of the function or global scope. The variable becomes known at the top but stays undefined until the assignment line.

let and const also get hoisted, but they do not behave the same. They sit in a “temporal dead zone” between the top of the scope and the line where they appear. You cannot use them before the declaration line.

console.log(x); // undefined
var x = 5;

console.log(y); // ReferenceError
let y = 10;

Output:

undefined

/index.js:4
console.log(y); // ReferenceError
^

ReferenceError: Cannot access 'y' before initialization
at Object.<anonymous> (/index.js:4:13)

In the example above, x is hoisted and becomes undefined at first. y is also hoisted, but it stays unreachable until the line where you define it.

So, how does JavaScript hoisting affect scope?

Hoisting works inside each scope. If you declare a variable inside a function with var, the hoisting only applies to that function.

function test() {
  console.log(a); 
  var a = 3;
}

test(); // undefined

In this case, the a variable gets hoisted to the top of the function. Global variables follow the same rule—var goes to the top of the global scope.

let and const still follow block scope, so if you define them inside an if block, they only live in that block. Hoisting still applies, but you cannot touch them early.

How JavaScript Engines Handle Hoisting

When the JavaScript engine starts, it scans the code and sets up memory for variables and functions. This happens before it runs any line of code.

The engine creates two phases:

  1. Compilation phase – It allocates memory for variables and functions. It hoists declarations to the top.
  2. Execution phase – It runs your code from top to bottom.

In the compile phase, var gets a memory slot with the value undefined. let and const get memory slots but stay uninitialized until the declaration runs.

The Difference Between Hoisting var, let, and const with Examples in JavaScript

Here is what changes when you use different keywords:

  • var gets hoisted and initialized with undefined.
  • let gets hoisted but not initialized. Access before the declaration throws an error.
  • const works like let, but you must assign a value when you declare it.
console.log(a); // undefined
var a = 1;

console.log(b); // ReferenceError
let b = 2;

console.log(c); // ReferenceError
const c = 3;

Output:

undefined

/index.js:4
console.log(b); // ReferenceError
^

ReferenceError: Cannot access 'b' before initialization
at Object.<anonymous> (/index.js:4:13)

var lets you write less strict code, but it leads to bugs. let and const make hoisting rules clearer.

How to Debug Hoisting in JavaScript

To avoid hoisting problems, follow these steps:

  • Declare variables at the top of their scope.
  • Always use let or const.
  • Use strict mode with 'use strict'; to catch mistakes early.
  • Do not rely on using functions or variables before you define them.

You can also use breakpoints in the browser’s developer tools. Step through the code to watch how the engine handles each line.

Hoisting in ES6

Before ES6, var and function declarations worked with hoisting only. ES6 added let, const, and block scope. These newer keywords changed how hoisting works.

Now, hoisting still happens, but the behavior of let and const adds a safeguard. The “temporal dead zone” stops you from using variables before they get declared.

Also, arrow functions and function expressions do not hoist like function declarations.

sayHi(); // Works
function sayHi() {
  console.log("Hi");
}

sayBye(); // TypeError
const sayBye = function () {
  console.log("Bye");
};

Output:

Hi

/index.js:6
sayBye(); // TypeError
^

ReferenceError: Cannot access 'sayBye' before initialization
at Object.<anonymous> (/index.js:6:1)

Function declarations hoist the full function. Function expressions do not. That is why the second case fails.

Let’s move on to the following section to see more examples of hoisting in JavaScript.

Examples of Hoisting in JavaScript

Here are a few more clear examples:

function demo() {
  console.log(x); // undefined
  var x = 10;
}

demo();

The x variable moves to the top inside the demo function. You see undefined.

{
  console.log(b); // ReferenceError
  let b = 5;
}

Output:

/index.js:2
console.log(b); // ReferenceError
^

ReferenceError: Cannot access 'b' before initialization
at Object.<anonymous> (/index.js:2:15)

Here, b sits in the temporal dead zone. You cannot use it early.

foo(); // "hello"

function foo() {
  console.log("hello");
}

Function foo works fine. The full function hoists.

bar(); // TypeError

var bar = function () {
  console.log("world");
};

Output:

/index.js:1
bar(); // TypeError
^

TypeError: bar is not a function
at Object.<anonymous> (/index.js:1:1)

The variable bar hoists but only gets undefined. You call it before the assignment.

Wrapping Up

Hoisting can confuse you if you do not know how it works. Once you understand how JavaScript handles declarations before it runs code, the behavior starts to make sense.

var, let, and const all get hoisted, but they act differently. Functions may hoist too, but only if you use function declarations.

You do not need to avoid hoisting. You just need to write code that works with it. Keep your declarations at the top.

Use let and const to make your scope and timing clear. If you get an error or unexpected value, check how hoisting might have caused it.

Thank you for reading. Click here to see more JavaScript tutorials.

FAQs

Do all variables hoist in JavaScript?

Yes. All declarations hoist, but only var allows early use. let and const hoist but block access until the line you define them.

Do functions hoist too?

Yes. Function declarations hoist in full. Function expressions do not.

Why does hoisting exist?

JavaScript compiles your code before it runs. Hoisting comes from that process. It helps manage memory and scope setup before execution.

How do I avoid hoisting issues?

Use let and const. Keep declarations at the top of your scope. Avoid calling functions or using variables before you define them.

Is hoisting good or bad?

It is just how JavaScript works. You must understand it. If you write clean code, it will not cause problems.
Previous Article

PHP rtrim Function: Remove Trailing Characters or Whitespace

Next Article

Git Delete Branch: Remove Local and Remote Git Branches

Write a Comment

Leave a Comment

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

Subscribe to Get Updates

Get the latest updates on Coding, Database, and Algorithms straight to your inbox.
No spam. Unsubscribe anytime.