I Don't Know JS Yet: Hoisting
Tags: webdev, javascript, codenewbie
Published: 2020-11-10 18:11:56

In the [last post](https://dev.to/thehumzahasan/i-don-t-know-js-yet-declaration-and-scope-4hpf), we discussed the concept of declaration and scope of a variable in javascript. But what if we end up using a variable or a function before its declaration. That's where hoisting comes into play.

In simple word, **Hoisting is a Javascript behaviour of moving all the declarations to the top of the current scope**. 

###*Variable Hoisting*
Let's visualize this with a small code snippet, the below code can be treated as a low-level example of hoisting.

```javascript
x = 'I will be hoisted';
console.log(x);
var x;
```
This code is internally converted by JS execution context to the below snippet
```javascript
var x;
x = 'I will be hoisted';
console.log(x);
``` 
The output in both the case will be 
```javascript
I will be hoisted
```

Thus we are safe in saying that the variable defined with **'var'**, have their declaration hoisted to the top of their present scope.

 
Now let's take another example to explore the concept of hoisting in a bit more depth. 

```javascript
x = 5;
console.log(x);
console.log(y);
y = 10;
var x, y;

/*Output:
5
undefined
*/
```
If we have a look at the output we would see the first console statement giving us '5', but the second console will give us 'undefined'. This is because as mentioned, in hoisting only the declaration are hoisted to the top of the scope but the initializations are not hoisted. 

So in this example, although when the compiler encounters the *console.log(y)* statement, it hoists the variable declaration to the top, the variable is still not initialized. 

The above code can be thought of the following:
```javascript
var x, y;
x = 5;
console.log(x);   //5
console.log(y);   //undefined
y = 10;
```

####**In Hoisitng, only the declaration is hoisted to the top and not the initialization.**

We have seen that the variables declared with 'var' are hoisted, but when you come to 'let' and 'const', it's a different story!

Let's take a look at these code snippets to get a better understanding. 
```javascript
/*Scenario 1*/
x = 9;
console.log(x);
let x;

// Error : Uncaught ReferenceError: Cannot access 'x' before initialization

/*Scenario 2*/
y = 9;
console.log(y);
const y;

//Error : Uncaught SyntaxError: Missing initializer in const declaration
```
So it's safe to say that only variable declared with *var* are hoisted to the top of the scope but the variables declared with *let* and *const* aren't. 
 
###*Function Hoisting*

Although both are called hoisting, function hoisting is different from variable hoisitng. In **Function Hoisitng, not just the function name is hoisted but also the actual function definition is hoisted.**

Let's take a quick look at the following code snippet,
```javascript
isItHoisted();

function isItHoisted() {
    console.log("Yes!");
}
```
This internally means same as,
```javascript
function isItHoisted() {
    console.log("Yes!");
}
isItHoisted();
```
The above snippet will result in *'Yes!'*, because in the first case even though we call the function first and then declare it, internally the definition is hoisted and to the top and then it's called. 

 *An important note which be should take is the fact that only function definition can be hoisted and not function expression.*