Hoisting in JavaScript

A practical breakdown of why Next.js is our preferred framework for scalable web applications.
In JavaScript, hoisting is the default behavior of moving all declarations to the top of their scope before code execution. This gives us the advantage of being able to reference functions and variables regardless of where they are declared—whether in the global or local scope.
One of the most common effects of hoisting is that it allows us to call functions before they are written in the code.
Note: JavaScript only hoists declarations, not initializations.
undefined vs ReferenceError
Example 1
console.log(typeof variable); // Output: undefined
In JavaScript, an undeclared variable is assigned the value
undefined at execution time, and its type is also
undefined.
Example 2
console.log(variable); // Output: ReferenceError: variable is not defined
A ReferenceError is thrown when attempting to access a variable that has not been declared.
Hoisting Functions
JavaScript functions can be loosely classified into the following two types:
Function Declarations
hoisted(); // Output: "This function has been hoisted."
function hoisted() {
console.log("This function has been hoisted.");
}
Function declarations are fully hoisted, meaning they can be called before they appear in the code.
Function Expressions
expression(); // Output: TypeError: expression is not a function
var expression = function () {
console.log("Will this work?");
};
In this case, the variable declaration is hoisted, but the function
assignment is not. As a result, JavaScript sees expression as a
variable rather than a function, leading to a TypeError.
Hoisting Classes
JavaScript classes can also be classified into two categories:
Class Declarations
var Hero = new Honda();
Hero.height = 100;
Hero.weight = 300;
console.log(Hero); // ReferenceError: Hero is not defined
class Honda {
constructor(height, weight) {
this.height = height;
this.weight = weight;
}
}
Unlike variables declared with var, class declarations are
hoisted but remain uninitialized. Attempting to access them before
declaration results in a ReferenceError.
The correct approach is:
class Honda {
constructor(height, weight) {
this.height = height;
this.weight = weight;
}
}
var Hero = new Honda();
Hero.height = 100;
Hero.weight = 300;
console.log(Hero); // { height: 100, weight: 300 }
Class Expressions
var Hero = new Honda();
Hero.height = 10;
Hero.width = 10;
console.log(Hero); // TypeError: Honda is not a constructor
var Honda = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
Class expressions are not hoisted in the same way as class declarations. The variable is hoisted, but the class definition is not initialized until execution.
Named Class Expressions
var Honda = class Honda {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
var Hero = new Honda();
Hero.height = 10;
Hero.width = 10;
console.log(Hero);
Conclusion
Hoisting is a powerful JavaScript feature that can lead to both flexibility and confusion. Understanding how variables, functions, and classes are hoisted helps developers write safer, more predictable code and avoid subtle runtime errors.
Share this insight