Hoisting in JavaScript

Hoisting in JavaScript

Hoisting is the default behavior of JavaScript where all the declarations are moved to the top of their scope. In simple words, we can use a variable or call a function before it is declared. Hoisting is a unique concept of JavaScript, and in this post, let us learn about hoisting basics with some examples.

A simple example of Hoisting 🚩

console.log(name); // Undefined
var name="matrixread";

sayHello("NEO"); // Hello NEO
function sayHello(name){
    console.log(`Hello ${name}`);
}

As we can see in the above example we are calling a function before it is declared and it gets executed normally. However, hoisting acts differently based on the scenario, let’s have a look at some of them.

Only declarations are Hoisted

JavaScript only hoists declarations but not their initialized values.

console.log(year); // Undefined
var year; // Declaration
year = 6; // Initialization

Hoisting inside Functions

As per the definition, Hoisting moves declarations to the top of their respective scope and if a variable is declared inside a function then its declaration is hoisted to the top of the functional scope.

function add(){
   console.log(a); // Undefined
    var a = 2;
}

console.log(b); // ReferenceError: b is not defined
function divide(){
    var b = 2;
}

let and const are not Hoisted

Variables declared with let and const throw a reference error when we access them before they are declared. Hence it is recommended to always declare the variables before using them.

console.log(day); 
// ReferenceError: Cannot access 'day' before initialization
let day = "Friday";

console.log(month); 
// ReferenceError: Cannot access 'month' before initialization
const month = "May"; 

Function expressions are not Hoisted

Only function declarations are hoisted.

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

Function expressions are not hoisted.

greet(); // TypeError: greet is not a function
var greet = function(){
    console.log("Hello there!");
}

Hoisting with Classes

Class declarations

JavaScript classes are hoisted but they are uninitialized until evaluation i.e we cannot use them before they are declared.

var snowBall = new Cat();
 snowBall.height = 20;
 snowBall.weight = 10;
 console.log(snowBall); // ReferenceError: Cat is not defined

 class Cat {
   constructor(height, weight) {
     this.height = height;
     this.weight = weight;
   }
 }

Class expressions

Like functions, class expressions are not hoisted.

var stuart = new Dog();
 stuart.height = 20;
 stuart.weight = 10;
 console.log(stuart); // TypeError: Dog is not a constructor

 var Dog = class {
   constructor(height, weight) {
     this.height = height;
     this.weight = weight;
   }
 }

Undeclared variables are not Hoisted

As we are aware that we can use variables in JavaScript without declaring (i.e without using var, let, const) but, these undeclared variables are not hoisted as they are not declared.

console.log(site); // Throws ReferenceError exception
site="Matrixread.com";

Conclusion

There is an argument that let, const, and classes are not hoisted, because we cannot use them before they are declared so we can assume that they are not hoisted. But, some say that let, const, and classes in JavaScript are hoisted but they are un-initialized.

Whatever may be the case the best way is to declare, initialize, and then use.

Reference