Explain What Hoisting Is in JavaScript

February 13, 2023

☕️ Support Us
Your support will help us to continue to provide quality content.👉 Buy Me a Coffee

The article titled What Is the Difference Between var, let and const in JavaScript? discusses the differences between var, let, and const in JavaScript and how they behave with regards to hoisting. This article provides a more detailed explanation of what hoisting is and the differences in hoisting behavior.

What Is Hoisting?

Most people may have used a function before declaring it when writing JavaScript code, such as the following code:

sayHello(); // Hello

function sayHello() {
  console.log("Hello");
}

However, executing such code will not report an error, and the reason is because of hoisting.

Hoisting is not a formal definition in the ECMAScript® 2015 Language Specification, but it is used to describe the concept of storing variable and function declarations in memory during the JavaScript compilation phase.

This feature causes function and variable declarations to be hoisted to the top of the scope, even if they are actually defined below. Note, however, that the JavaScript engine doesn't actually move the code to the top, it's just a description of the concept.

Variable and Function Hoisting

var Hoisting

var hoisting means that during the compilation phase, the JavaScript engine will hoist allvar variable declarations to the top of the function scope. Although the variable declaration is hoisted, it will not be assigned a value. In the following code, the result of calling name early will be undefined instead of Tom.

console.log(name); // undefined
var name = "Tom";

let Hoisting

Many people mistakenly believe that let does not hoist, because if we use it before declaring let, we will get the following error.

console.log(greeting); // Uncaught ReferenceError: greeting is not defined
let greeting = "hi there";

The above code throws an error not because let has no hoisting. Although hoisting is not defined in the standard specification, conceptually, let and const also have hoisting behavior, but there are the following differences:

  1. var will be hoisted to function scope, but let and const will only be hoisted to block scope.
  2. When var creates a variable and defines the variable scope, it will automatically initialize the variable value to undefined at the same time. However, when let hoists the variable to block scope, it will not initialize the variable. This state can be called uninitialized, and there is another common saying that variables defined by let and const currently exist in the Temporal Dead Zone (TDZ).

Function Hoisting

Function declarations are also hoisted. The difference from var hoisting is that function hoisting also creates function objects, so they can be called before declarations.

foo(); // 1
function foo() {
  console.log(1);
}

However, it should be noted that if it is a function expression, the promotion behavior will be the same as the declared variable. In the following code snippet, the foo function declared with var, when used before the declaration, the current value will be undefined, so calling undefined will throw an error.

foo(); // Uncaught TypeError: foo is not a function
var foo = function () {};

When the foo function declared with let is used before the declaration, foo is in the temporary dead zone at this time, so calling foo will report an error.

foo(); // Uncaught ReferenceError: foo is not defined
let foo = function () {};

Why Is There a Temporal Dead Zone (TDZ) Error?

Many articles mention that the benefit of the Temporal Dead Zone (TDZ) error is to prevent us from using a variable before it is declared. However, there is another key design concept.

As the author of You Don't Know JS explains in this course, the TDZ error is actually designed for const. Imagine if const had the same hoisting behavior as var. In that case, accessing a const variable before its declaration would return an undefined value. However, we know that const is a constant, and its value should not change in the same scope. If we first get undefined and then a different value, it would violate the specification. Therefore, the TDZ error was designed to prevent this situation from happening.

☕️ Support Us
Your support will help us to continue to provide quality content.👉 Buy Me a Coffee