Understanding Hoisting in JavaScript
Tags: javascript, programming, softwaredevelopment
Published: 2017-04-28 17:34:00

---
title: Understanding Hoisting in JavaScript
published: true
description: In this article about JavaScript, I'll explain what hoisting is and show different examples so that you can better understand what it's all about.
tags: javascript, programming, software development
canonical_url: https://www.designingforscale.com/understanding-hoisting-in-javascript/
---

You know JavaScript, but do you really _know_ JavaScript? It's a great language, even though some may argue otherwise. Sure, it's got some bad parts, but it has improved a lot in past years and developers are getting much better at using JavaScript _correctly_ and at following best practices. Strict mode is also getting better at preventing newer developers from making some bad JavaScript mistakes and unfortunately running into unwanted behaviours.

However, not everyone has heard of the term **Hoisting** or knows what it means. In this article, I'll explain what hoisting is and show different examples so that you can better understand what it's all about.

![Learning](https://www.designingforscale.com/content/images/2017/03/laptopAndBooks.png)

#### The JavaScript Interpreter
When you execute your JavaScript code, the interpreter goes through the code twice. 

The first run through the code is where it does a safety check and small optimizations of your code. Safety checks such as making sure that the syntax is right, if there are any calls to `eval` or `with`, etc. Then, it optimizes the code as best as it can to ensure better performance when it is executed. This is also where hoisting occurs (more on this soon), and is referred to as the _compile_ run.

The second run is where it actually executes your code by going through it line by line, doing the assignments, calling the functions, and so on.

#### What is Hoisting?
Hoisting is when the JavaScript interpreter moves all variable and function declarations to the top of the current scope. It's important to keep in mind that only the actual declarations are hoisted, and that assignments are left where they are.

Hoisting is done during the interpreter's first run through the code.

#### Variable Declarations
Let's start with a basic example and look at the following code:

```javascript
'use strict';

console.log(bar); // undefined
var bar = 'bar';
console.log(bar); // 'bar'
```

At first, you may think that the sample code would throw a `ReferenceError` on line 3 (`console.log(bar);`) because `bar` has not been declared yet. However, with the magic of hoisting, it won't throw a `ReferenceError` but the value of `bar` will be `undefined` at that point. This is because the JavaScript interpreter does a first run through the whole code and declares all variables and functions at the top of the current scope, and then, on the second run, will execute the code.

Here's what the same code would look like after the interpreter's first run:

```javascript
'use strict';
var bar;
console.log(bar); // undefined
bar = 'bar';
console.log(bar); // 'bar'
```

Notice how `bar` is now declared at the top (`var bar`) but is not yet assigned at that point? It's a subtle but important difference, and this is why `bar` is logged as `undefined` instead of throwing a `ReferenceError`.

#### Function Declarations
Hoisting also applies to _function declarations_ (not _function expressions_). Let's analyze the following sample code:

```javascript
'use strict';

foo();
function foo() {
    console.log(bam); // undefined
    var bam = 'bam';
}

console.log(bam); // ReferenceError: bam is not defined
```

In this sample code, we are able to successfully call the function `foo` since it's a _function declaration_ and therefore it is hoisted as-is to the top of the current scope. Then,  `foo` will output `undefined` when calling it since, as in the previous example, `bam` is hoisted to the top of its current scope, which is `function foo()`. This means that `bam` was declared before calling `console.log(bam)` but it has not yet been assigned a value (`bam = 'bam'`).

However, the important thing to note here is that `bam` was hoisted at the top of its **current** scope. This means that it was **not** declared in the global scope but in the function's scope instead.

Here's what the same code would look like after the interpreter's first run:

```javascript
'use strict';

function foo() {
    var bam;
    console.log(bam); // undefined
    bam = 'bam';
}

foo();
console.log(bam); // ReferenceError: bam is not defined
```

Notice how `foo()` was moved to the top, and `bam` is declared in `foo()`? This means that, when you call `console.log(bam)` on line 10, it will not find the variable `bam` in the general scope and will throw a `ReferenceError`.

#### Function Expressions
Next, the third use case I'd like to cover is how _function expressions_ are not hoisted as opposed to _function declarations_. Instead, it's their variable declarations that are hoisted. Here's some sample code to demonstrate my point:

```javascript
'use strict';

foo();
var foo = function () {
    console.log(bam); // undefined
    var bam = 'bam';
}
```

This code throws a `TypeError: foo is not a function` error since **only** the variable declaration `var foo` is hoisted to the top of the file, and the assignment of the function to `foo` is done on the interpreter's second run only.

Here's what the same code would look like after the interpreter's first run:

```javascript
'use strict';

var foo;
foo(); // `foo` has not been assigned the function yet
foo = function () {
    console.log(bam);
    var bam = 'bam';
}
```

#### What Takes Precedence?
Finally, the last use case I'd like to cover is that _function declarations_ are hoisted **before** variables. Let's look at the following code:

```javascript
'use strict';

console.log(typeof foo); // 'function'

var foo = 'foo';

function foo () {
    var bam = 'bam';
    console.log(bam);
}

```

In this example, `typeof foo` returns `function` instead of `string`, even though the function `foo()` is declared after the variable. This is because _function declarations_ are hoisted before _variable declarations_, so `foo = 'foo'` is executed on the second run, **after** we call `typeof foo`. 

On the first run, the interpreter will hoist `foo()` at the top of the current scope, and then will get to the `var foo = 'foo'` line. At that point, it realizes that `foo` was already declared so it doesn't need to do anything and will continue its first run through the code.

Then, on the second run (which basically _executes_ the code), it'll call `typeof foo` before it gets to the assignment `foo = 'foo'`.

Here's what the same code would look like after the interpreter's first run:

```javascript
'use strict';

function foo () {
    var bam = 'bam';
    console.log(bam);
}

console.log(typeof foo); // 'function'
foo = 'foo';
```

#### ES6

ES6 is the future and is what most developers will be using moving forward, so let's see how hoisting applies for ES6 code.

Hoisting doesn't apply the same way for `let` and `const` variables compared to `var` variables, as we saw above. However, `let` and `const` variables are still hoisted, the difference being that they cannot be accessed until the assignment is done at runtime.

From <a href="https://tc39.github.io/ecma262/#sec-let-and-const-declarations" target="_blank">ES6's documentation</a>:

> The variables are created when their containing Lexical Environment is instantiated **but may not be accessed in any way until the variable’s LexicalBinding is evaluated.**

At the end of the day, it's a small technicality where the interpreter applies hoisting to these variables on the compile run but they'll throw reference errors when accessed before the assignment happens, essentially preventing us from accessing these variables before their assignment.


#### Conclusion
I hope this clarifies how hoisting works in JavaScript. It's definitely not as tricky or complicated as it sounds, but it does require us to breakdown the different use cases and trying different scenarios to understand how things work under the hood.

Do not hesitate to leave me comments or questions if you have any - I'd love to hear your feedback.

*This post was originally published on [Designing for Scale](https://designingforscale.com/?utm_source=hoisting&utm_medium=guest-post&utm_campaign=devto)*