Hoisting in JavaScript

Jennifer Takagi
The Startup
Published in
3 min readAug 20, 2020

In the past month, I finally understood a really amazing behavior about Javascript’s architecture: the famous Hoisting! Let’s dive into this curious topic and understand more about var, let, const and JS scope.

Hoisting is the default behavior of Javascript that moves all the declarations (variables and functions) to the top of the scope. In a nutshell… it doesn’t matter where you declare it, they will be hoisted to the top of the code before the execution.

Hoisting a hope
Hoisting JavaScript

First, let’s understand the Javascript lifecycle:

$ var magicNumber; //declaration
> undefined
$ a = 30; // initialisation/assignment
> 30
$ a + 20; // usage
> 50

When you declare a variable and before being assigned, its primitive value is undefined. After there is the assignment phase where we define a value to this variable and in the end, we can then use our variable.

There is an eccentric and dangerous behavior about hoisting, undeclared variables do not exist until the code executes. So, assigning a value to an undeclared variable creates a global variable! And global variables always cause double trouble: mutability everywhere! :(

$ function hoistBehavior () {
firstName = 'Jennifer';
var lastName = 'Takagi';
}
$ hoistBehavior();
$ console.log(firstName);
> 'Jennifer'
$ console.log(lastName);
> lastName: lastName is not defined

In the example, the variable firstName is undeclared. This variable jumped over the declaration step and went ahead to the assignment… becoming a global variable, because of that we can access it in all code! On the other hand, the variable lastName was declared as var, so it will be kept in the function scope.

ES5 (var)

In ES5 the only way to declare a variable is writing the keyword: var, and all the behaviors that were explained until this point occur with this kind of declaration.

$ console.log(name);
> undefined
$ var name = 'Jennifer';

Under the hood, Javascript made these following steps: it hoisted the declaration of var name and executed all the code, row by row:

$ var name;
$ console.log(name);
> undefined
$ name = 'Jennifer';

ES6 (let and const)

Using ES6 we have two ways to declare a variable: let and const. On this version, Javascript changed the declaration and initialization of the variables, let’s take a look…

let

Maybe you already know this but when we declare a variable as let, it will belong to a block scope and not a function scope. Like the example below, because I declared lastName with let keyword, this variable only exists into the if scope!

$ if (name === 'Jennifer) {
let lastName = 'Takagi;
}

$ console.log(lastName);
> Uncaught ReferenceError: lastName is not defined

const

To declare variables using const is the most elegant way because this keyword keeps the immutability of the variable once you declare it:
1) you have to assign the value straight away;
2) you won’t be able to change its value.
(Why does this happen? :O I will write another post about this, I promise…)

$ const name;
> Missing initializer in const declaration
$ const name = 'Jennifer';
> undefined
$ const name = 'Jenni';
> Uncaught SyntaxError: Identifier 'name' has already been declared

In conclusion, we can say the difference between ES5 and ES6+ is how JS initializes the variable: if it declared with let and const it remains uninitialized at the beginning of execution. Otherwise if declared with var it is initialized with a value of undefined.

--

--

Jennifer Takagi
The Startup

Developer focused on technology for troubleshooting! A clean code lover, functional programming enthusiast and passionate about sharing knowledge.