"Hoisting in JavaScript"

In JavaScript, hoisting allows you to use functions and variables before they are declared. Let's learn what hoisting is and how it works.

What is hoisting?

console.log(num);
var num = 5;

Can you guess what should be the output of this code, it might surprise you but this code outputs undefined and doesn't throw an error even though num gets assigned after we console.log it.

This is because the JavaScript interpreter splits the declaration and assignment of functions and variables it hoists your declarations to the top of their containing scope before execution.

Variable Hoisting in JavaScript:

In Javascript, we can declare variables through var, let and const.

Variable hoisting acts differently depending on how the variable is declared.

Variable hoisting with var :

When the interpreter hoists a variable declared with var, it initializes its value to undefined. As we have seen in the above example which gave us the output as undefined. But using an undeclared variable will throw a ReferenceError because no declaration was hoisted.

consol.log(num); //Uncaught ReferenceError: num is not defined

This unusual behavior of JavaScript can lead to errors. Using a variable before its declaration is usually not desirable.

But let and const variables introduced in ECMAScript behave differently.

Variable hoisting with let and const:

Variables declared with let and const is hoisted but is not initialized with default values. Accessing a let and const variable before it's declared will result in a ReferenceError.

console.log(num); //Uncaught ReferenceError: Cannot access num before initialization
let num = 45;

But here also the interpreter still hoists num: the error message tells us the variable is initialized somewhere.

The temporal dead zone:

Do you know the reason why we get a reference error when we try to access the let and const variable before its declaration is because of the temporal dead zone. As the temporal dead zone starts at the beginning of the variable's enclosing scope and ends when it's declared. Accessing the variable in this zone throws a Reference error.

{
   //Start of foo' temporal dead zone
   let bar = "bar"
   consolo.log(bar); //"bar"
   console.log(foo); //ReferenceError beacuse we are in the temporal dead zone 
   let foo = "foo" //End of foo's temporal dead zone
}

The temporal dead zone is also present in default function parameters, which are evaluated from left to right.

function foobar(foo = bar, bar = 'bar') {
  console.log(foo);
}
 foobar(); //uncaught Referenceerror cannot access 'bar' before initialization

type of in the temporal dead zone:

Using the let and const variables as an operand of the type of operator in the temporal dead zone will throw an error. This behavior is consistent with the other cases of letting and const. The reason that we get a reference error here is that i is declared but not initialized, we should be aware that we're using it before initialization.

But this is not the case with var variable before declaration because it is initiated with undefined when it's hoisted.

Function hoisting in JavaScript:

In JavaScript, functions are also hoisted. Function hoisting allows us to call a function before it is defined.

foo(); //"foo"
function foo() {
 console.log('foo');
}

The main thing with function hoisting is only function declarations are hoisted and not the function expressions. If we try to call the variable that the function expression was assigned to we will get a TypeError or ReferenceError .

foo(); // uncaught typeerror : foo is not a functiom
var foo = function() {}
bar(); //Uncaught ReferenceError: cannot access 'bar' before initialization
let bar = function() {}
foo(); // uncaught ReferenceError : foo is not defined

Function declarations are hoisted, which means that is easy to reference the function before it is defined in the file. This harms readability and maintainability.

Thanks for reading, I hope this post about hoisting in JavaScript helps you in learning.