DEV Community

Cover image for What is Hoisting and how it works in JavaScript?
Santan kr Sharma
Santan kr Sharma

Posted on

What is Hoisting and how it works in JavaScript?

Hoisting is JavaScript concept which make JavaScript different from language Java.

In Java every variable created in code have block level scope. Means if we have create any variable that will have its visibility limited into that block in which it was declared.

So if we use variable above from the declaration it will gives error.

But in the JavaScript, the variables can be used before declared, this kinds of mechanism is called Hoisted. It’s a default behavior of JavaScript.

Hoisting is JS’s default behavior of defining all the declarations at the top of the scope before code execution. One of the benefits of hoisting is that it enables us to call functions before they appear in the code. JavaScript only hoists declarations, not initializations. You can find the official documentation Here.

Understanding what exactly is JavaScript Hoisting
Variable declaration and initialization occur in the following sequence:

Declaration –> Initialization/Assignment –> Usage

// Variable lifecycle
let x;                 // Declaration
x = “hoisting”;        // Assignment
console.log(x);        // Usage
Enter fullscreen mode Exit fullscreen mode

Most importantly, you should always remember that the JavaScript declares the variable first in the background. Then, initializing them. Thus, it is also good to know that the processing of variable declarations takes place before the execution of any code. However, until the execution of code assigning them takes place the undeclared variables do not exist in JavaScript.
Therefore, when the assignment is executed, a value assigned to an undeclared variable implicitly creates it as a global variable. This specifies that all undeclared variables are global variables.

// hoisting
function Hoisting(){
  x = 100;
  let y = 200;
}
Hoisting();
console.log(x); // 100
console.log(y); // Reference Error: y is not defined
Enter fullscreen mode Exit fullscreen mode

In the above code sample, there is a function called Hoisting(). Thus, we have a variable which we didn’t declare using let/var/const and a let variable y. The assigning of the undeclared variable to the global scope is done by JavaScript. But for variable y, we get a ReferenceError.

Hosting in Function scoped variable

In ES5, we consider the var keyword. Hoisting with var is somewhat different in comparison to let/const. The example with var to see how hoisting works:

var num (global)
console.log(car);    // undefined
var car = ‘Lamborgini’;
Enter fullscreen mode Exit fullscreen mode

In the above code, when logging the variable name which was declared and assigned later than using it, the compiler gives an “undefined” result. This was not expected as we should have got ReferenceError as trying to use the car variable even before declaring it.
But the interpreter sees this differently, which is as follows:

//how interpreter sees the above code
var car;
console.log(car); // undefined
car = ‘Lamborgini’;
Enter fullscreen mode Exit fullscreen mode

The let and const Keywords.

Variables and constants declared with let or const are not hoisted!
JavaScript Initializations are Not Hoisted
JavaScript only hoists declarations, not initializations.

var a = “volkswagon”; // Initialize a
var b = “Lamborgini”; // Initialize b
elem = document.getElementById("car"); // Find an element
elem.innerHTML = a + " " + b;       // Display a and b as volkswagon and lamborgini
Enter fullscreen mode Exit fullscreen mode

In the above code, since the declaring of variables takes place before the results. As a result, the execution of the code prints the result of variable a and b.

var a = “i10”;  // Initialize a
elem = document.getElementById("car");      // Find an element
elem.innerHTML = "a is " + a + “ and b is " + b;  // Display a and b
var b = “Lamborgini”;  // Initialize b
Enter fullscreen mode Exit fullscreen mode

Result:
a is i10 and b is undefined
Hence, this is because only hoisting of the declaration (var b) takes place, not the initialization (= “Lamborgini”) to the top. Because of hoisting, b has been declared before it is used, but because initializations are not hoisted, the value of b is undefined.

Hoisting classes

JavaScript classes can be classified into two classes:

*Class declarations
*Class expressions

In Class declarations
They are much like function counterparts. Therefore, this means no hoisting of JavaScript class declarations. However, they remain uninitialized until evaluation. Thus, this effectively means that you have to declare a class before you can use it.

var car1 = new car();
car1.height = 5;
car1.weight = 500;
console.log(car1);   // Output: ReferenceError: car is not defined
class car{
  constructor(height, weight) {
    this.height = height;
    this.weight = weight;
  }
}
Enter fullscreen mode Exit fullscreen mode

In the above code, the reference error occurs. This is because, after initialization of the car1 variable, the defining of car class is takes place. To solve this error, we just need to define the car class before car1 initialization. This is hosting in the class declaration.

class car{
  constructor(height, weight) {
    this.height = height;
    this.weight = weight;
  }
}
var car1 = new car();
car1.height = 5;
car1.weight = 500;
console.log(car1);
Enter fullscreen mode Exit fullscreen mode

Therefore, this gives the proper result.
In Class expressions
They are much like their function counterparts. Therefore, this means no hoisting of class expression.
Therefore, below is an example with the un-named or anonymous variant of the class expression:

var rect = new shapes();
rect.height = 10;
rect.width = 20;
console.log(rect); // Output: TypeError: shapes is not a constructor
var shapes = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
Thus, the correct way to do it is like this:
var shapes = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
var rect = new shapes();
rect.height = 10;
rect.width = 20;
console.log(rect);
Enter fullscreen mode Exit fullscreen mode

Summary

To many developers, Hoisting is an unknown behavior of JavaScript. Many developers overlook it’s importance as well. Moreover, if a developer doesn’t understand hoisting, programs may contain bugs (errors). In order to avoid bugs, always declare all variables at the beginning of every scope. Thus, this is how JavaScript interprets the code, it is always a good rule.

Discussion (0)