Hoisting in JS. (Part 1 - variable Hoisting)
Published: 2021-02-02 12:23:19

<b>Prerequisite:</b> Basic knowledge of JS

#**What is Hoisting?**

In simple words, it means you can use a variable before declaring it (variable declaration is a must).

Ok, what that means? Can’t I use a variable without declaring it?

No, you can’t. You have to declare a variable to use it.

For example:

![Screenshot 2021-02-01 at 11.48.05 PM](https://dev-to-uploads.s3.amazonaws.com/i/991j5kqf99i29k17aunz.png)
 
I am using variable **x** without declaring it and I got an error. This behavior is common in almost all programming languages. (I guessed)

Ok, now you know that you have to declare a variable to use it.

But now you have the below questions:
1. What do you mean by variable declaration?
2. How JS engine know that this is a variable declaration?
3. Where should I declare a variable? I mean physical location in your code. That is either before or after using a variable?
4. Where is hoisting in all of this?

Let answered them one by one.

###**What do you mean by variable declaration?**

In JS, If you want to store data in your code you use variables to store them. For that, you inform the JS engine by saying that “Hey JS engine, I want to store some data in my code so I am going to declare a variable to just inform you.”

**var x;**  

This is called a variable declaration. `var x` this exact piece of code tells the JS engine that you declare a variable and named it **x**.

JS provides 3 keywords to declare a variable.

`var
const 
let`

In this article, I will use the **var** keyword.

Just Remember when you declare a variable with **var** keyword, behind the scene JS engine allocates memory for it. That's why you have to declare a variable to use it.

> **JS engine** is responsible for executing your JS code. Your JS code is feed into the JS engine and then it spits out the final output. That’s why browsers understand JS code because every major browser comes with its own JS engine like chrome have V8 engine, the edge has Chakra, Mozilla have SpiderMonkey.

Check more: [List of JS engine](https://en.wikipedia.org/wiki/List_of_ECMAScript_engines)


###**How does the JS engine know that this `var x` is a variable declaration?**


These keywords *(var, const, let)* help the JS engine to identify that a variable is declared.
 
So when the JS engine sees the below code:

![Screenshot 2021-02-02 at 12.20.17 AM](https://dev-to-uploads.s3.amazonaws.com/i/pdw7u7ulhe97923ts747.png)

JS engine is like “Oh I got it. You declared a variable.”

###**Where should I declare a variable? I mean physical location in your code. That is either before or after using a variable?**


To answer this question, let me show you 2 examples.

 
![Screenshot 2021-02-02 at 12.24.40 AM](https://dev-to-uploads.s3.amazonaws.com/i/099u98m4bysrlj1wc9be.png)

![Screenshot 2021-02-02 at 12.25.08 AM](https://dev-to-uploads.s3.amazonaws.com/i/j2icta6wq7snjibiu393.png)
  
 

In 1st example, I first declare a variable and then use it by printing its output.
In 2nd example, I first use it by printing its output and then declare the x variable.

In most programming languages, you cannot use a variable before declaring it.

But in JS, you can. And that's where hoisting comes into the picture.

###**Where is hoisting in all of this?**

Both ways of declaring variable in JS are fine until you use `"use strict"` in your code._(called strict mode)_

In strict mode, you cannot use a variable before declaring it.

But to understand hoisting, we skip the strict mode.

In beginning, I told you that hoisting helps you to use a variable before declaring it with the **var** keyword. 

can you guess the output of the below code?

```
console.log(x);
var x;
```

```
var x;
console.log(x);
```

Both will print `undefined`. This means **x** gets `undefined` as the default value.

###**How variable ** x ** get  `undefined` as the default value?**

Let go step by step.

> If you do not assign a value to a variable then by default JS engine assigns `undefined` as the default value. Yes, `undefined` is a value in JS like number (1,2,3...) and character (a,b,c....)

Ok, so both ways of writing look similar then where is the difference?

The difference comes in how the JS engine parse it.
To understand that you need to understand the different phases your code goes through.

JS engine has 2 phase: 
1. Memory creation phase
2. Execution phase

```
var x;
console.log(x);
```

Let's understand how the JS engine parse the above code.

When the JS engine sees `var x`, then it sees it as variable declaration, remember our 2nd question *How JS engine know that this is a variable declaration?*

So after seeing it as variable declaration, JS engine takes the variable **x** and store it in memory and assign `undefined` as its value. This happens in the **Memory creation phase**.

In the **Execution phase**, when it sees `console.log(x);`, the JS engine says "I know what **x** is. I already store it in memory during **memory creation phase**." And since the JS engine already assigned `undefined` as its value in this phase, so you will get `undefined` output.

####Explanation:- 

During the **memory creation phase**, JS engine recognizes variable declarations as it reads the code, initializes them to `undefined`, and puts them into memory to be used during the execution.

So when JS engine start executing your code (**Execution phase** started), all variable we use in the code, JS engine confirms their existence from **Memory creation phase**.

![Screenshot 2021-02-01 at 11.48.05 PM](https://dev-to-uploads.s3.amazonaws.com/i/991j5kqf99i29k17aunz.png)

Now you know why we get a Reference error in the above code.
When JS engine see `console.log(x);`, It says "Ok... I do not see the **x** variable stored in memory. (Why?) because there is no variable declaration code, so when it goes through the **memory creation phase** it stores nothing in memory.
And since the JS engine does not find the location/ reference of the **x** variable in memory, so it throws a Reference error.


Few...take a break because the next one is tricky.

```
console.log(x);
var x;
```

Let start with how the JS engine will parse this code.

Till now basic understanding will be like this, JS engine will see `console.log(x);`, and then it will throw a Reference error same as what we see in the last example.

But that's, not the case. Remember that our JS code will go through 2 phases. (memory and execution phase)
So first JS engine will parse the complete code to identify all the variable declarations and then put them in memory with `undefined` as their values. 

![Screenshot 2021-02-02 at 2.24.59 PM](https://dev-to-uploads.s3.amazonaws.com/i/b6crpl5dxgahutzx0wen.png)
 

Now behind the scene, your code looks like this.

![Screenshot 2021-02-02 at 2.32.56 PM](https://dev-to-uploads.s3.amazonaws.com/i/e4ibimt916le2lkb145c.png)
 
Now you get to know why few folk say that in hoisting your variable declaration move at the top of your code. Actually, it happened behind the scene, not on your actual code.

Once the memory creation phase complete, your code moves to the execution phase. Now JS engine sees this `console.log(x);` code and say "Yup I know it. This **x** variable I already save in memory in last phase.". Then it will print `undefined` as output.

You see hoisting magic. You can access the **x** variable before declaring it. In c# or java you can't access them before. You will get error there.

####Quiz

```
console.log(a);
var a = 10;
console.log(a);
a = 20;
console.log(a);
```
> Hint: variable declaration is hoisted. Initialization do not.

`var a` => this is variable declaration.
`= 10` => this is initialization.

Comment your output and share how the above code looks behind the scene after going through the JS engine phases.

##Summary

Hoisting simply means you can access the variable before declaring it. It has its own pros and cons. But if you do not like hoisting then write code in strict mode (`use strict`).

I know `let` & `const` are not cover but let save them for a future post.
Part 2 will cover how hoisting works with function. Is it the same or diff? 


Please share your thoughts here or on LinkedIn. If I missed something please comment below, I will update the post.

Thank you.