skip to content
Slashism

Hoisting in JavaScript

/ 3 min read

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

Let’s understand the hoisting for different variable declarations and function:

Hoisting of var

var variables are hoisted to the top of their scope and initialized with a value of undefined.

console.log(villain); // ReferenceError: villain is not defined
console.log(hero);
var hero;
hero = 'Batman';
console.log(hero);

In the above example, the villain variable is not declared in the entire code snippet. So console.log(villain) will throw an error and break the script execution. This means other lines won’t execute.

Get rid of the first line console.log(villain) in the above example and try again:

console.log(hero); // accessing before it was initialized
var hero;
hero = 'Batman';
console.log(hero);

In the above example, we are trying to access hero variable before it was initialized. So hero variable here will hoist on top of this scope. Now console.log(hero) would print undefined instead of breaking the script execution this time.

This hoisting mechanism works internally so you wouldn’t see the code moving like that but internally the above code would turn into something like this:

var hero; // It came on the top automatically (internally)
console.log(hero); // 'undefined'
hero = 'Batman';
console.log(hero); // 'Batman'

Notice the var in the above examples? Let’s change that to let or const and see what happens.

Hoisting of let and const

let and const variables are hoisted to the top just like var variables. But there is a difference - For var declaration, hoisted variables are initialized as undefined but that’s not the case with let and const declaration.

So if we pull up the same examples from the var declaration:

console.log(hero); // ReferenceError: hero is not defined
let hero;
hero = 'Batman';
console.log(hero);

If you run the above code (we have let now instead of var), you will get a Reference Error. So always initialize your variables before using them.

Hoisting of Functions

Functions are also hoisted on top of the scope just like variables.

// First example
eatCookie();
function eatCookie() {
console.log('Eating 🍪');
}
// Second Example
function eatCookie() {
console.log('Eating 🍪');
}
eatCookie();

The two examples above would work the same because functions with their entire content would be hoisted to the top. So the first example would internally turn into the second example.

But, there is a catch 😁

eatCookie(); // ❌ TypeError: eatCookie is not a function
var eatCookie = function() {
console.log('Eating 🍪');
}

So what happened in the above example?

If you notice, we have not declared a function but an expression that acts like a function. So eatCookie would hoist to the top as a variable and instead of the function body, it would be initialized with undefined.

Please note, that this case is valid only if we use var. But if a function expression is declared using a let and const then this would throw a ReferenceError because let and const cannot be initialized like var variables, just like we discussed earlier.

This is why you should always initialize your variables and functions first, before using them.

Here is a cookie 🍪 for reading all of this and reaching to the end.