Demystifying function and variable hoisting in JavaScript
Tags: javascript
Published: 2020-01-27 15:35:35

---
title: Demystifying function and variable hoisting in JavaScript
published: true
date: 2020-01-27 03:55:55 UTC
tags: javascript
canonical_url: https://blog.logrocket.com/demystifying-function-and-variable-hoisting-in-javascript/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/bqdthx0gs4bf3gdfl3sm.png
---
**Written by [Gbolahan Olagunju](https://blog.logrocket.com/author/iamgbols/)**✏️

There are several topics that are quite difficult to wrap one’s head around when working with JavaScript, because they aren’t as intuitive as they should be or as we expect them to be.

Developers coming from a language background other than JavaScript can have a particularly difficult time with certain concepts.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

In this article, we will be looking at the intricacies of function and variable hoisting.

There are several ways to define functions in JavaScript. We will be taking a look at the following three methods:

- Function Declaration
- Function Expression
- Arrow functions.

```jsx
// function declaration 
function welcome () {
console.log('Welcome to learning JavaScript');
}

// function expression 
// invloves the assignment of a named or an anonymous function to a variable.
var welcome = function () {
console.log('Welcome to learning JavaScript');
}

// arrow function
var welcome = () => console.log('Welcome to learning JavaScript');

//we can simple call it with
welcome(); // Welcome to learning JavaScript
```

At first glance, the above ways of defining a function look the same.

However, there are subtle differences.

Let’s look at them — for the purposes of this article, we will be focusing more on function declaration and function expression.

```jsx
double(5) // 10
square(2) // Uncaught ReferenceError: Cannot access 'square' before initialization
   // at <anonymous>:3:1
const square = function (x) {
 return x * x;
}

function double (x) {
return 2 * x;
}
```

As we can see, the program doesn’t work as expected.

However, if we comment out the calling of the square function at line 3 or move it below its definition, we can see that the program works as expected.

The reason for this anomaly is that we can call a function declaration before it is actually defined, but we can’t do the same for a function expression. This has to do with the JavaScript interpreter, which interprets a given script.

Function declarations are hoisted, while function expressions aren’t. The JavaScript engine hoists function declarations by lifting it up the current scope before actually executing the script.

As a result, the above snippet is actually interpreted as follows:

```jsx
function double (x) {
return 2 * x;
}
double(5) // 10
square(2) // Uncaught ReferenceError: Cannot access 'square' before initialization
   // at <anonymous>:3:1
const square = function (x) {
 return x * x;
}
```

But the square function isn’t hoisted, which is why it is only available from the definition downwards to the rest of the program. This resulted in an error when it was called.

This is the case with function expression.

There is also another form of hoisting that happens in JavaScript, which occurs when a variable is declared using the keyword `var`.

Let’s look at a few examples that illustrate this:

```jsx
var language = 'javascript';
function whichLanguage() {
        if (!language) {
                var language = 'java';
        }
        console.log(language);
}
whichLanguage();
```

When we run the above code, we can see that our console logs out `java`.

If this surprises you, you’re in the right place. We’re going to take a closer look at exactly what is going on.

In the same way function declarations are hoisted, variables are declared with the keyword `var`.

There are a few things to note about the differences in how they are hoisted:

1. When a function declaration is hoisted, the whole function body is moved to the top of the current scope.

2. A variable declared using the keyword `var` when hoisted only moves the variable name to the top of the current scope — not the assignment.

3. Variables declared using the keyword `var` are only scoped by a function, not an `if` block or a `for` loop.

4. Function hoisting supersedes variable hoisting.

With these rules in mind, let’s see how the JavaScript engine will interpret the above code:

```jsx
var language = 'javascript';
function whichLanguage() {
var language;
        if (!language) {
                language = 'java';
        }
        console.log(language);
}
whichLanguage();
```

As we can see, the `var language` was moved to the top of the current scope, thus giving it a value of `undefined`. That makes it enter the `if` blocks, which reassigns it to a value of `java`.

Let’s look at another example that further demonstrates this:

```jsx
var name = 'gbolahan';
function myName() {
        name = 'dafe';
        return;
        function name() {}
}
myName();
alert(name);
```

We can deduce what the above code will produce by following the rules of how the JavaScript engine will interpret the file.

Let's see how it is interpreted:

```jsx
var name = 'gbolahan';
function myName() {
function name() {} // hoisted name function
        name = 'dafe';  // name reassigned to a new value. 
        return;    
}
myName(); 
console.log(name);
```

`gbolahan` will be logged out because the name defined in the `myName` function is scoped by that function and is discarded after the function is execution.

### Conclusion

This covers most of the things to consider when working with hoisting in JavaScript. There are a few exceptions to these rules, but with the introduction of ES6 you’re now able to avoid many of these caveats by using the  `const` and `let` keywords when declaring variables.

It helps to have an understanding of how hoisting works, particularly since you’re likely to come across it during JavaScript interviews.

* * * 
## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *

The post [Demystifying function and variable hoisting in JavaScript](https://blog.logrocket.com/demystifying-function-and-variable-hoisting-in-javascript/) appeared first on [LogRocket Blog](https://blog.logrocket.com).