Skip to main content

Command Palette

Search for a command to run...

Hoisting

Updated
6 min readView as Markdown
Hoisting
A

Welcome! I'm Ayoola Ayodele, a passionate senior software developer specializing in Javascript, Node.js, Next.js, and React.js. With extensive experience in the field, I have honed my skills as both a developer and a technical writer.

Throughout my career, I have authored numerous programming articles, primarily focused on Javascript. These articles cover a broad spectrum of topics, ranging from fundamental concepts to advanced techniques. I take pride in my ability to simplify complex subjects and present them in an accessible manner for my audience.

My journey as a Full-Stack Developer has allowed me to contribute to exciting projects. For instance, I built a virtual study platform that facilitates student connections via video chat using React.js, Node.js, and webRTC.

My technical skill set includes expertise in React.js, Node.js, MUI, Express.js, JavaScript, and TypeScript. I am committed to delivering high-quality code and embracing continuous learning to stay ahead of industry trends.

I am eager to tackle new challenges and collaborate with talented individuals to create remarkable solutions. I am eager to tackle new challenges and collaborate with talented individuals to write and build something great together!

Curiosity has always been my key to unlocking a deeper understanding of concepts. By asking important questions like "why," "how," and "what," I have been able to grasp complex ideas more effectively. In this article, we will delve into the world of hoisting in JavaScript and provide answers to fundamental questions such as: What is hoisting? Why is it essential to learn about hoisting? And best practices to follow to deal with it. Additionally, I will present relatable examples that will solidify our understanding of this intriguing concept.

What is Hoisting?

Hoisting is a JavaScript feature that moves variable and function declarations to the top of their respective scopes during the compilation phase, regardless of where they are actually placed in the code. The word hoist means lift or move. It's as if the JavaScript engine elevates or lifts the declarations to the top, making them available for use throughout their respective scopes.

Let's see hoisting in action with the example below:

Example 1: Variable Hoisting

console.log(myVariable); // Output: undefined
var myVariable = 42;
console.log(myVariable); // Output: 42

In the code above, even though the variable myVariable is accessed before its declaration, it does not throw a ReferenceError. Instead, the variable is hoisted or lifted to the top of its scope, resulting in the initial value of undefined.

Example 2: Function Hoisting

sayHello(); // Output: "Hello Ayodele!"
function sayHello() {
 console.log("Hello Ayodele!");
}

In this case, the function sayHello is called before its declaration. Due to hoisting, the function is moved to the top of its scope, allowing it to be invoked successfully.

Why does Hoisting Happen?

Hoisting happens because JavaScript needs to know about all the variables and functions that are going to be used in a program before it can start executing the code. By hoisting these declarations to the top of their respective scopes, JavaScript can ensure that it has all the information it needs to run the program correctly.

How can I avoid problems with hoisting?

Accessing variables before declaration is a bad practice and should be avoided. The best way to avoid it is by getting an error when attempting to do so; which is what TDZ (Temporal Dead Zone) ensures.

Temporal Dead Zone (TDZ)

The Temporal Dead Zone is a behavior introduced in ECMAScript 2015 (ES6) with the introduction of let and const declarations. It refers to the period between the creation of a binding (variable declaration) and the point at which it is initialized. During this period, any attempt to access the variable results in a ReferenceError.

Why was TDZ introduced in ES6?

The introduction of TDZ was a deliberate design choice to improve JavaScript's behavior and address issues related to variable hoisting and scoping. The TDZ ensures that variables declared with let and const are not accessed before they are assigned a value, promoting better code quality and reducing potential bugs.

To better understand what TDZ aims to solve, we would look at hoisting with var and hoisting let and const separately. Also, we would look at the relationship between hoisting and TDZ (Temporal Dead Zone) in the context of Function Expressions.

Hoisting with var

Variables declared with var are hoisted to the top of their scope during the compilation phase. However, only the declaration is hoisted or moved, not the initialization. This means that the variable is assigned the value undefined until the actual assignment is reached in the code. To avoid hoisting-related issues with var, it is best practice to declare variables at the top of their scope and initialize them later.

console.log(myVar); // Output: undefined
var myVar = 42;

Only myVar is the declaration lifted or moved to the top of their scope during the compilation, not the initialization. That was why it was assigned the value of undefined until the actual assignment was reached, var myVar = 42

Hoisting with let and const

Variables declared with let and const also experience hoisting, but with a slight difference. Unlike var, variables declared with let and const are not initialized until their actual declaration is reached in the code. Like we did in the previous example, it will not assign undefined to it. This behavior is known as the Temporal Dead Zone (TDZ). If you try to access a let or const variable before its declaration, you will encounter a ReferenceError.

console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization
let myLet = 50;

Function Declaration and Hoisting

When you use a function declaration, the entire function is hoisted or moved to the top of its scope during the compilation phase. This means that you can invoke the function anywhere in the scope, even before the actual function declaration in the code.

sayHello(); // Output: "Hello Ayodele, I am a hoisted function!"

function sayHello() {
 console.log("Hello Ayodele, I am a hoisted function!");
}

In this example, sayHello is a function declared using the function declaration syntax. We can call sayHello( ) before or after the actual declaration because the entire function is hoisted to the top.

Hoisting with Function Expressions

When you use a function expression, the variable declaration is hoisted to the top of its scope during the compilation phase. However, unlike function declarations, the function itself is not hoisted. This means that you cannot invoke a function expression before the variable is initialized.

Let's look at one example, then we will look at the code together.

sayHello(); // ReferenceError: Cannot access 'sayHello' before initialization
const sayHello = function () {
  console.log("Hi Dapo! This function is not hoisted");
};

In this example, only const sayHello declaration was moved to the top of its scope but its initialization that it is the function itself was not hoisted or moved. I mean this function, function () { console.log("Hi Dapo! This function is not hoisted"); };

When we try to call sayHello() before the actual declaration, JavaScript throws a reference error due to the TDZ (Temporal Dead Zone) restriction. The variable sayHello is hoisted, but the function itself is not initialized yet.

Best Practices

  • Don't use var to declare variables. Use const most of the time and let if there is a need for variable reassignment.
const myName = "Ayodele"   //use this
var myName = "Ayodele"    //Don't use var
let alias = "Ay" //Use let when you are sure of reassignment
alias = "Ayoola"
  • In other to write clean code, you should declare your variable at the top of each scope.
const myAge = 30
console.log(myAge)
  • Always declare all your functions first and use them only after declaration and this applies to all types of function
const greetings = function() {
console.log("We have declared first and initialized with a function")
}
console.log(greetings())

Conclusion:

Understanding hoisting in JavaScript is very important for writing clean, bug-free code. By knowing how variables and functions are hoisted, we can avoid unexpected behavior and make our code more readable and maintainable. Remember to follow best practices and declare variables at the top of their scope to ensure clarity and to leverage the benefits of hoisting in your JavaScript projects. Happy coding