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.
Table of Content
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(); // undefinedIn 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:
- Compilation phase – It allocates memory for variables and functions. It hoists declarations to the top.
- 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:
vargets hoisted and initialized withundefined.letgets hoisted but not initialized. Access before the declaration throws an error.constworks likelet, 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
letorconst. - 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?
Do functions hoist too?
Why does hoisting exist?
How do I avoid hoisting issues?
Is hoisting good or bad?
Similar Reads
JavaScript optional chaining lets you access object values without runtime errors. It checks if a property exists before access and…
The Math.acos function finds the angle in radians from a cosine value in JavaScript. It gives a value between 0…
JavaScript switch statement checks many values without long chains. It appeared to replace stacked conditions that slow you down. Understand…
The current essay is devoted to the basic principles and introduction of JavaScript. This language no longer needs to be…
Click a button on a website. Something changes. A menu opens or a message pops up. That’s how JavaScript works.…
Math.exp is a built-in JavaScript function that returns the value of e raised to a given number. Here, e is…
This guide shows how toSorted function works in JavaScript with arrays. It covers syntax, rules, and examples for numbers, text,…
JavaScript gives you the Math.round() function to deal with decimal numbers. You use it when you want to round a…
JavaScript Ninja Code points to ways that help a person write code that runs fast and stays easy to read.…
Data types in JavaScript help hold values and shape code rules. They set clear plans for text, numbers, and other…