MediumHoisting in JavaScript. Hoisting questions appear in almost… | by Nikhil Lal Pawa | Medium
Sitemap
Nikhil Lal Pawa

Nikhil Lal Pawa

FullStack Developer | IITian | React | SpringBoot | TypeScript | PostgeSQL | Learning

Hoisting in JavaScript

4 min readDec 2, 2025
Press enter or click to view image in full size

Hoisting questions appear in almost every JavaScript interview — and most developers still misunderstand it.
Ask any JS developer, and they’ll say, “hoisting is when JavaScript moves all variable declarations to the top of the scope”.

But the truth is deeper.

JavaScript actually reads your code twice — once to prepare, and once to execute.
Most of the “weird” behavior we see comes from what happens in that first hidden pass.

Let’s break down what hoisting really means.

The Four Types of Hoisting (According to MDN)

1. Being able to use a variable’s value in its scope before the line it is declared. (“Value hoisting”)

2. Being able to reference a variable in its scope before the line it is declared, without throwing a ReferenceError, but the value is always undefined. ("Declaration hoisting")

3. The declaration of the variable causes behavior changes in its scope before the line in which it is declared.

4. The side effects of a declaration are produced before evaluating the rest of the code that contains it.

We’ll go through each of them one by one

1. Being able to use a variable’s value in its scope before the line it is declared. (“Value hoisting”)

console.log("my name is ", getName()); // my name is Nikhil Lal Pawa
function getName() {
return "Nikhil Lal Pawa";
}

This gets compiled into

// compiled code
function getName() {
return "Nikhil Lal Pawa";
}
console.log("my name is ", getName()); // my name is Nikhil Lal Pawa

In the above example, JavaScript moves the function and its value to the top of the scope. Hence, value hoisting.

2. Being able to reference a variable in its scope before the line it is declared, without throwing a ReferenceError, but the value is always undefined. ("Declaration hoisting")

console.log("my name is ", name); // my name is undefined
var name = "Nikhil";

This gets compiled into,

// compiled code
var name = undefined;
console.log("my name is ", name); // my name is undefined
name = "Nikhil";

In case of “var” variables, JavaScript only moves the declaration to the top, making it possible to access the variable earlier in the scope (here, the scope doesn’t include the block scope), but the value will be set as undefined.
Hence, Declaration hoisting.

Get Nikhil Lal Pawa’s stories in your inbox

Join Medium for free to get updates from this writer.

Before moving forward, I want to discuss one interesting question that was asked of me in an interview

Does JS hoist const/let?

let a = 5;

if (a === 5) {
console.log(a); // ReferenceError: Cannot access 'a' before initialization
const a = 6;
}

See the above example — the variable “a” defined outside the if: outerA and the variable “a” defined within the if: innerA— Even though the variable outerA is defined before the variable innerA is defined, JS throws a reference error as if innerA is blocking access to it, called the Temporal Dead Zone. So, obviously, something fishy is going on there; this is the third type of hoisting.

3. The declaration of the variable causes behavior changes in its scope before the line in which it is declared.

Here the innerA declaration causes behavior changes in its scope, to make sense of it, one can think that JS hoists the declaration at the top of the scope but doesn’t initialize it with any value, so JS knows that this variable is defined in the scope but its value is yet to be initialized so JS throws an error if it is accessed earlier creating a temporal dead zone of the variable.

So, answering the question of whether Const and let are hoisted. It is yes. But this is a controversial topic. So if you answer in an interview stating that there is no hoisting of const and let, it would not be considered a wrong answer, but obviously, it will give you brownie points if you can explain what I talked about above.

Now to the last type of hoisting.

4. The side effects of a declaration are produced before evaluating the rest of the code that contains it.

That is the hoisting of Import statements. I’ll give a small example which will help you understand this.

I have two files in the same directory, exportFile.js and temp.js

// exportFile.js
export var toExport = 5;


// temp.js

const toAdd = 15;
console.log("added exported var and toAdd", toExport + toAdd); //20

import { toExport } from "./exportFile.js";

In the above example, it doesn’t matter where the import statement is written — it is always processed first, and the imported module is evaluated before the rest of the file and before any top-level code in temp.js runs.

The behavior above applies only to ES Modules (ESM) — the module system that uses import and export. ESM is statically analyzed, which means JavaScript knows all imports before executing any code. That’s why import declarations are hoisted and processed first.

CommonJS (require()), on the other hand:

is not statically analyzed

2. does not hoist require() calls

3. executes require() at runtime, in the order they appear

To summarize, hoisting is the way JavaScript’s compilation phase makes declarations available for the entire scope before any code runs.

Or, in simpler terms, hoisting is when a piece of code starts affecting other parts of your code before it is defined in the code.

Understanding hoisting unlocks a much clearer mental model of how JavaScript truly works.
If you found this helpful, share it with someone who’s preparing for JavaScript interviews or strengthening their fundamentals.
Follow me for more clear, practical JS insights like this.

--

--

Nikhil Lal Pawa
Nikhil Lal Pawa

Written by Nikhil Lal Pawa

FullStack Developer | IITian | React | SpringBoot | TypeScript | PostgeSQL | Learning