Every Wonder What is Hoisting? let's understand JavaScript's Built-in Behaviour
Published: 2024-05-11 13:59:14

Ever wonder what's the deal with hoisting in JavaScript? 🤯 Don't fret! This article is here to help you get a good grasp of the two terms.

So relax, grab your favorite cup of coffee ☕️, and let’s get started with Hoisting. 

### **Prerequisite: Execution Context**

Before we dive into the fascinating world of hoisting, let's first understand the basics of execution context in JavaScript.

With every code execution, JavaScript creates an execution context. As part of this process, JavaScript creates a virtual object for each variable and initializes them with a value of `undefined`. This ensures that even before code execution begins, variables have a designated space in memory. So, if we attempt to access a variable before it's initialized, **it will return `undefined`.**

## **What is Hosting?**

In the MDN document it shows like this.

> JavaScript **Hoisting** refers to the process whereby the interpreter appears to move the *declaration* of functions, variables, classes, or imports to the top of their scope, prior to execution of the code.
> 

OR

> In JavaScript, hoisting refers to **the built-in behavior of the language through which declarations of functions, variables, and classes are moved to the top of their scope – all before code execution**. In turn, this allows us to use functions, variables, and classes before they are declared.
> 

yup i know definition wont help much, Let's unpack this with some examples.

## Let consider the following - 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z893fntyouqeantnkour.png)

In the above example everything seems to work as expected. This is a normal function code and output is also we get is obvious this is how code has to work but lets consider the below example.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5v6g0nvehtojr82i5qa4.png)

Here, we're calling variables and functions before they're even initialized. Surprisingly, JavaScript doesn't throw an error as many other programming languages would. Instead, it treats this behaviour as perfectly normal - 
**this is hoisting in action!**

**Now let us see how it works separately for variable and function.**

## Hoisting in Variable

## **VAR**

Consider this example:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcg8686yjgxs6dbyq0c3.png)
Surprisingly, this outputs **`undefined`** instead of causing chaos. How? Well, during compilation, JavaScript sets aside memory for **`name`** and assigns it the value **`undefined`** until it's properly initialized. It's like reserving a seat at the table before the guest arrives! 🪑

When JavaScript code is executed, it goes through a process known as the execution phase. During this phase, JavaScript creates what's called an execution context for each code execution. Think of it as setting the stage for the code to run smoothly.

As part of setting up this execution context, JavaScript allocates memory for variables but doesn't assign them any values yet. Instead, it initializes them with a special value called **`undefined`**. This essentially reserves a spot in memory for each variable, marking it as empty or uninitialized.

Now, if we attempt to access or reference a variable before it's been assigned a value during this initialization phase, JavaScript returns the default value for uninitialized variables, which is **`undefined`**. This behavior ensures that the code doesn't crash or throw errors when trying to access variables that haven't been explicitly defined yet.

So, in the context of hoisting, when we access a variable before it's been initialized, JavaScript doesn't throw an error. Instead, it returns **`undefined`**, indicating that the variable exists but hasn't been assigned a value yet. This behaviour is fundamental to how JavaScript handles variable declarations and hoisting.

## **Let and Const**
Like Var let and const are also hoisted but there is some difference, consider the following example


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/euj569mu46a8032o89q2.png)
In the above code the output is Reference:…” 
but why var give undefined and let and const give reference error.

Unlike **`var`**, they throw a reference error when accessed before declaration. This is due to the concept of the Temporal Dead Zone (TDZ)

### Temporal dead zone (TDZ)

Ever heard of it? Well, it's a bit of a mouthful, but don't worry, we'll break it down.

When we declare a variable using **`let`**, **`const`**, or **`class`**, JavaScript creates what's called a "temporal dead zone" (TDZ) for that variable. Now, this TDZ is like a waiting room – it's where the variable sits before it gets its value.

During the TDZ period, which starts as soon as the block containing the variable begins and ends when the variable is declared and initialized, the variable exists, but it hasn't been given a value yet. So, if you try to access it during this time, JavaScript gets a bit cranky and throws a **`[ReferenceError].`**

But here's the interesting part: once JavaScript reaches the declaration of the variable and gives it a value, the TDZ ends, and the variable becomes accessible. If no initial value was specified during the declaration, JavaScript initializes the variable with a value of **`undefined`**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20swu7gh7ctltl8wbwqb.png)

Now, compare this to **`var`** variables. With **`var`**, if you try to access a variable before it's declared, JavaScript doesn't throw an error – it just returns **`undefined`**. This is because **`var`** variables are hoisted to the top of their scope, giving them a head start in the code execution process.

So, why "temporal" dead zone? Well, it's because this zone depends on the order of execution, not the order in which the code is written. Take this example: even though a function using a **`let`** variable appears before the variable is declared, it's called outside the TDZ, so everything works smoothly.

### **Hoisting in Functions**

Ever tried calling a function before it's even declared? Well, in JavaScript, you can do just that! Unlike variables, functions don't throw an error when you try to use them before declaring them. Instead, they give you the whole function. Interesting, right?

**Now, let's dive into how hoisting works with functions.**

Consider this scenario:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4861913htgwhwuwikqur.png)

Here, we get the output as the whole function. Ever wonder why? It's because when JavaScript runs this code, we know that function is added in the memory component as whole in the execution context and when we call this function with out initilizing it give whole function and output.. 

So, even if you call the function before declaring it, JavaScript already knows about it and happily executes it without any complaints.

But wait, there's a twist! When you use a function expression or an arrow function, things work a bit differently. In these cases, JavaScript treats the function as a variable. So, before the function is declared, JavaScript stores **`undefined`** for it in memory. When you call the function without initializing it, it returns **`undefined`**

**Function Declaration and arrow function:**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8n465t5zgdjzl2dua6ly.png)
In the above example, we get different outputs for function expression and function declaration or arrow function. Why? Because when you use function expression or arrow functions, JavaScript considers them as variables. So, before the function is initialized, JavaScript stores **`undefined`** for it in memory. When you call the function without initializing it, it returns **`undefined`**.

So, next time you wonder why functions behave differently than variables when it comes to hoisting, remember this little quirk!

### **Wrap Up**

In summary, hoisting is JavaScript's behind-the-scenes magic that rearranges declarations, allowing us to use them before they're officially declared. Understanding this behavior is crucial for writing more efficient and effective JavaScript code.

So, the next time you encounter hoisting in your code, you'll know exactly what's happening behind the scenes!

**Thanks for Reading!** 😃

Connect with Me! 🙋🏻‍♀️
My Website - https://shreyajoshi.tech/
Instagram - https://www.instagram.com/codebyshreya/
LinkedIn - https://www.linkedin.com/in/codebyshreya/
Linktree - https://linktr.ee/codebyshreya

Happy Coding! 🎉