Easy!
Hoisting is a JavaScript thing that means that you can use a variable before you declare it...
Hold up, what?
Yeah, you're right, let me dig into this a little bit...
Firstly, we need to understand the definitions of these 2 words:
declared
defined
This is declaring a variable -
var greeting;
```
***************
This is **defining** a variable -
greeting = "Hello, how are you?"
Secondly, let's think about *scope*
_I wrote a little example of what **scope** is on my Twitter_
_Let's run with this analogy..._
For your little people to be able to work locally, they need to have been **declared**. Any people in your factory that haven't been declared can be seen by **everyone** in other factories within your code - they are _global._
####Ok, that's scope. Can we talk about hoisting now?
Actually, no. Ok kinda.
_Where you put stuff matters_
Let's think back to our **declared** and **defined** again. There are 2 different ways you can do these things:
_Simultaneusly_:
var greeting = "Hello world"
In this example, we are **declaring** the variable (greeting) at the same time as **defining** what it is going to say ("Hello World")
###or
_not.....simultaneously..._
var greeting
....
greeting = "Hello World"
In this example, we are **declaring** the variable (greeting) and then later on in the code, we are **defining** what it is ("Hello World")
###Why are there 2 ways of defining and declaring, isn't that kinda confusing? 1 way would be easier...
_My thoughts entirely._
Personally, I prefer the first way, I think it looks nicer and is easier to read
However, it is also nice to make all of your **declarations** at the top and then you can **define** them wherever you like.
Anyway, moving on...
###Hoisting?
Yes, yes.
So we have looked at the different ways of declaring and defining, but what JavaScript also lets you do....is this...
greeting = "Hello World"
...
var greeting
Now, logically, you shouldn't be able to do this, because you are using the variable before you are declaring it with the **var** keyword. It _should_ throw an error, but it doesn't. It will still know what **greeting** is. This is because the JavaScript compiler quickly scans your code and _hoists_ all of your declarations up to the top, as if you had written it like this:
var greeting
greeting = "Hello World"
It essentially _knows_ that you might have declared variables in random places (because everyone writes differently!) and wants to pull them all up to the top before it starts properly working on what you have written.
I think that's pretty logical actually.
**It's like quickly reading a list of names in your head to make sure you know how to pronounce them all _before_ you read them out loud and get stuck!**
So, if you get an 'undefined' error on a variable that you weren't expecting, check the order that you've written everything in, and then blame hoisting (and probably start using let and const*) 🤣
Also, you may have noticed that I have used *var* as my JavaScript keyword throughout the examples. This is on purpose:
* `var` is a bit of a weird one - using it means that you might get some 'undefined' errors. `var` doesn't stand up for itself and is pretty unsure about things.
When you use `let` or `const` instead, they don't let the compiler boss them around - they know their job and they are sticking with it. `let` and `const` aren't affected by hoisting.
If you've **defined** something before you've **declared** it, you'll get a Reference error, and you don't need to worry about hoisting moving things around for you.
Hoisting also works with function declarations:
This is written in a logical order and works as expected. No hoisting involvement.
function example() {
var a = 1;
return a;
}
console.log(example())
//1
************************
This one is written with the `console.log` first, but will still work as expected because of hoisting - the compiler has skim read your code and 'hoisted' (pulled) all of your variable declarations to the top!
console.log(example())
function example() {
var a = 1;
return a;
}
//1
The lesson here: **stop using var, it will do you no good**
Understanding hoisting is still essential for when you have to work with older codebases (`let` and `const` haven't always been around to save you from hoisting!)
####Shoutouts:
* Big shoutout to [@pasoevi](https://twitter.com/pasoevi) for helping to proofread!
Top comments (1)
Knowing about JS execution context can help. Check out devopedia.org/hoisting