# JavaScript Hoisting Internals

# Introduction
Welcome to the third post of the series, [JavaScript: Cracking the Nuts](https://hashnode.com/series/javascript-cracking-nuts-ckawn7vc5007dl6s164ogqplz). In this post, we will learn about another fundamental JavaScript concept called `Hoisting`. 

As the series's focus is to get to the basics and internals of every concept, we will try exploring the internals of Hoisting here than just scratching the surface.

> If you haven't got a chance to read through the earlier posts of the series yet, you can find them here:
- [JavaScript Interpreted or Compiled? The Debate is Over](https://blog.greenroots.info/javascript-interpreted-or-compiled-the-debate-is-over-ckb092cv302mtl6s17t14hq1j)
- [Understanding JavaScript Execution Context like never before](https://blog.greenroots.info/understanding-javascript-execution-context-like-never-before-ckb8x246k00f56hs1nefzpysq)

# What do we know so far
Here is some recap from the last few posts of the series:
- In JavaScript, the source code typically goes through several phases before it is finally executed. The phases are, Tokenizing, Parsing, and Code Generation.
- Whenever a JavaScript code runs, it creates something called [Execution Context](https://blog.greenroots.info/understanding-javascript-execution-context-like-never-before-ckb8x246k00f56hs1nefzpysq). It helps in determining what code is currently running and helps in allocating memory for every function and variable declarations it finds on the way.

> The mechanism of allocating memory for the functions and variable declarations within an Execution Context is called ***Hoisting***.

# Demystifying some Myths
The word `Hoisting` is confusing and misleading in the context of what is actually happening here. That is one reason why many of the explanations of Hoisting are focused on the fact that variables and functions are hoisted. 

In plain English, Hoisting meaning, *raise (something) using ropes and pulleys*. At some point, one may start believing that things(variables and functions) actually being hoisted by moving their position up by the JavaScript engine.

 ![shock.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1593049888850/SkcO6B6JS.gif)

Hey, relax, nothing like that ever happens! Honestly, no code physically gets hoisted. It is all about how memory is allocated for functions, variable declarations in an Execution Context's [Creation Phase](https://blog.greenroots.info/understanding-javascript-execution-context-like-never-before-ckb8x246k00f56hs1nefzpysq).

We will see that with examples soon.

# Variable Hoisting
Consider this simple code:
```js
console.log('name is ', name);
var name;
name = 'tom';
console.log('name is ', name);
```
What's the expected output of the above code? Well, it is easy:

```shell
name is  undefined
name is  tom
```
The question is, why? We have accessed the variable `name` well before it has even been declared. Like many other programming languages, we should have got an error. But instead, we got `undefined`.

in JavaScript, the code execution context is divided into two phases:
- Creation Phase
- Execution Phase

In the creation phase, the memory gets allocated for the variables and initialized with a special value called `undefined`. 

> The meaning of `undefined` is, a variable has been declared, but it has no value assigned.

In the code example above, the creation phase declared the variable `name` by allocating memory for it and marked it as `undefined`. This phenomenon is called `Variable Hoisting` in JavaScript.

Later in the execution phase, the value `tom` gets assigned to the variable `name`, and the console log statements get executed. As the creation phase happens before the execution phase, we find the variables are already declared, i.e., created in memory(as in Hoisted).

# Function Hoisting
Function hoisting follows a similar path to variable hoisting. In function hoisting, JavaScript Execution Context's creation phase put the *function declaration* into memory. Let us understand it with this example:

```js
// Invoke a function, chase()
chase();

// Declare a function, chase()
function chase() {
  console.log('Tom chases Jerry!');
  // Invoke a function, caught();
  caught();
}

// Declare a function, caught()
function caught() {
  console.log('Tom caught Jerry :(')
}
```
The creation phase of the Execution Context creates a memory for the function `chase(),` and the entire function declaration has been put into the memory. In the execution phase, the entire function of the memory can be executed. 

As we know, the function creates its own execution context(Function Execution Context), the mechanism remains the same in the function execution context. First, create a memory for `caught()` and put the declaration into it. Later execute it.

![function_hoisting.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1593055331225/mLNMsYR07.gif)
*Created using [https://tylermcginnis.com/javascript-visualizer/](https://tylermcginnis.com/javascript-visualizer/)*

# Hoisting Rules

> A general rule of thumb is to always define functions, variables, etc., before using them in code. This can help in avoiding surprises and debugging nightmares.

There are a few guidelines and checks already put into JavaScript language to safe-guard from the pitfalls of using Hoisting without realizing it.

- JavaScript only hoists declarations, not initialization. With this, the following code is going to break:
 
 ```js
  test();

  var test = function() {
    console.log('I am being tested');
  }
 ```
 It will throw the following error because the `test` declaration is hoisted and initialized with `undefined` as a value. It was never assumed to be a function. It was, in fact, hoisted as variable hoisting, not function hoisting.

 ![hoisting_error_1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1593055794499/CeH_Gx1w6.png)

- `let` and `const` declarations are hoisted, too, but they are not initialized to `undefined` like `var`. See the example here:
 
 ```js
  console.log(foo);
  let foo;
 ```
 This will throw the following error but, it will just run fine with `var`:
 
 ![hoisting_error_2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1593056191691/t9mVGjVM2.png)

# Conclusion
As mentioned above, always define functions, variables, etc., before using them in code. Do not rely on Hoisting much. At the same time, it is important to understand the underlying concept of why certain things are behaving in specific ways.

%[<hr/>]
I hope you find the article useful. Please Like/Share so that it reaches others as well. If you enjoyed this article or found it helpful, let's connect. You can find me on [Twitter(@tapasadhikary)](https://twitter.com/tapasadhikary) sharing thoughts, tips, and code practices.

To get e-mail notifications on my latest posts, please subscribe to my blog by hitting the ***Subscribe*** button at the top of the page.

In the next post of the series, I'll be explaining another fundamental concept called `Scope`. Stay Tuned.
