Intro to Hoisting in JavaScript
Tags: javascript, beginners, tutorial
Published: 2022-06-01 12:49:42



![Hoisting Meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1crbbhga2x77zbtybhha.jpeg)

When learning to program in JavaScript you were told by instructors, mentors, or a random person on StackOverflow that you want to avoid hoisting issues in your code by using `const` or `let`. 

But you ask yourself, what the heck is hoisting and why do I need to avoid it? Well, this is the right place to be!

Hoisting is when the JavaScript engine moves variables and function declarations to the top of their respective scope before code execution.

Example of Hoisting variable declaration:

```
x = 6
var x;
console.log(x) 
// x would be equal to 6 with no errors thrown
```
Naturally, you would think this code would not work because you can't assign a variable and then have the declaration below that right? 

Well, you could do just that with `var` because it will initialize variables _before_ declaration, allowing JavaScript to _hoist_ it to the top of the function and not throw any errors.  

Example of Hoisting in function declaration:

```
dogBreed('Miniature Schnauzer')

function dogBreed(name) {
  console.log('My favorite dog breed is the ' + name + '!') 
}
// My favorite dog breed is the Miniature Schnauzer!
```
Although this code runs just fine, it is best practice to avoid invoking functions before declaring them for readability. 

Mixing these two together can lead to very confusing code. Take this code snippet for example: 

```
var dogBreed = "Pug";
var favDogBreed = function () {
  console.log("My favorite dog breed: " + dogBreed);
    var dogBreed = "Shih Tzu";
      console.log("Bob's favorite dog breed: " + dogBreed);
};

favDogBreed();
// Original favorite dog: undefined
// New favorite dog: Shih Tzu 
```
Confusingly enough, JavaScript initialized the first dogBreed to `undefined` because of _hoisting_ and then starts executing the function which is why we got this result. 

Variables that are initialized in JavaScript are not hoisted though. Interestingly enough, the code snippet below prints out `NaN`: 

```
console.log(x + y)
var x = 4
var y = 2
// Output is NaN
```
This happens because JavaScript is _hoisting_ `x` and `y` but not their respective initializations `= 4` and `= 2` resulting in `NaN` because `x` and `y` are not numbers!

Thankfully in 2015, we got the ES6 revision of JavaScript and that introduced `let` and `const` which effectively outdates `var`. 

Lets take another look `favDogBreed` but declare everything with `let` instead of `var`: 

```
let dogBreed = "Pug";
let favDogBreed = function () {
  console.log("My favorite dog breed: " + dogBreed);
    let dogBreed = "Shih Tzu";
      console.log("Bob's favorite dog breed: " + dogBreed);
};

favDogBreed();
// This will throw a ReferenceError and not let this code run
```
All is now right in the world and the engineer will have to go and fix their confusing code. 

However just because errors are thrown now, does not mean that hoisting is patched out of Javascript. It still occurs with variables declared with `let` and `const` but they are never initialized. Take this code snippet for example:

```
dogName = "Sparky";
const dogName
console.log(dogName)
// This code doesn't run

dogName = "Sparky";
let dogName
console.log(dogName)
// This results in a ReferenceError
```
What does this mean? For starters, hoisting is _still_ happening with these variables declared with `let` and `const` but there are some differences. 

`const` refuses run because of syntax error. Same thing happening with `let`, but JavaScript sees the variable and is aware of it, but JavaScript cannot use the variable until it has been properly declared.

When declared with `let`, our variable `dogName` is in this phenomenon called the _**temporal deadzone**_ which yes, would be the sickest name for a band but is what a variable declared with `let` or `const` is in until JavaScript reaches and executes the line where the variable is declared. 

The temporal deadzone does not apply to `var` because JavaScript initializes the variable to undefined when it is accessed _before_ the declaration.

The best practices to avoid hoisting issues is to: 

- Declare variables and functions `let` and `const` where ever you can

- Always declare variables at the beginning of each and every scope because this is how JavaScript and developers read code

- Never _ever_ use `var`

Congratulations! You now have a better idea of hoisting and how it works in JavaScript ES6. This (often overlooked) concept confuses developers both new and veterans alike and you have an edge in both understanding and avoiding hoisting related bugs in JavaScript!

Here are some additional resources on the topic:
[W3Schools](https://www.w3schools.com/js/js_hoisting.asp)
[MDN](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
[JavaScript Docs](https://javascript.info/var)