This post is to help my future self, specifically for the times when I am debugging JavaScript and trying to understand another one of it’s odd habits.
What is Hoisting?
When I first heard the term hoisting being applied to a programming language, my first thought was like a flag being raised up a flagpole, the JavaScript Just in Time compiler was moving code. Fortunately the MSDN page on Hoisting makes it clear this is not what happens.
Conceptually, for example, a strict definition of hoisting suggests that variable and function declarations are physically moved to the top of your code, but this is not in fact what happens. Instead, the variable and function declarations are put into memory during the compile phase, but stay exactly where you typed them in your code.
MSDN page on Hoisting retrieved 21/12/2020
Where it helps
Hoisting comes in useful when you want to to use a function before you declare it.
helloWorld();
// maybe lots of other code here
function helloWorld() {
console.log('Hello World!');
}
> Hello World!
In the example above the helloWorld function is called before it is declared.
Where it can catch you out
TL;DR: Initializations are not hoisted.
Again it’s worth quoting the following from the MSDN page on Hoisting.
JavaScript only hoists declarations, not initializations. If a variable is declared and initialized after using it, the value will be undefined
MSDN page on Hoisting retrieved 21/12/2020
which can be illustrated with the following:
console.log(booksRead);
var booksRead;
booksRead = 10;
> undefined
Combining declaration with initialisation still results in the same:
console.log(booksRead);
var booksRead = 10;
> undefined
Removing var results in a Reference Error.
console.log(booksRead);
booksRead = 10;
> index.js:3 Uncaught ReferenceError: booksRead is not defined
The same error is seen if you use let or const.