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
- Hoisting – MDN docs
- JavaScript basic concepts
- Understanding Hoisting in JavaScript