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
Scope.
What is scope?
Imagine that your functions are full of little people working away. Your functions are little factories.
All the people *inside* the factory cannot be seen by ANOTHER factory (function).
This is called 'local scope'13:08 PM - 17 Feb 2021
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 uselet
orconst
instead, they don't let the compiler boss them around - they know their job and they are sticking with it.let
andconst
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 for helping to proofread!
Top comments (1)
Knowing about JS execution context can help. Check out devopedia.org/hoisting