Back to Basics - JavaScript Hoisting 101
Tags: javascript, beginners
Published: 2019-08-06 23:29:50

---
title: Back to Basics - JavaScript Hoisting 101
published: true
description: reviewing the fundamentals
tags: #javascript, #beginners
---

It's always a good time to review the basics of your programming language!  In this series I'll be reviewing some fundamentals of JavaScript. It is important that we refresh ourselves on how the language works behind the scenes and of course it is also great practice to be able to explain concepts in simple terms. 

This week we review [Hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) - what it is, function and variable hoisting, and a few key takeaways.   

#### What is Hoisting?

When your JavaScript code is compiled, variable and function declarations are "hoisted" to the top of their scope. Depending on where a variable is declared, the scope could be global or local. Either way, the variable declaration is hoisted to the top of that specific scope. Functions are also hoisted, but to the very top of the program. Functions are hoisted even above global variables. Hoisting is why you might see functions successfully called before they are declared - to make this possible they are pulled (hoisted) to the top of your program right before the code is executed.

It is important to note that when code is hoisted it is not physically relocated in your program. Instead, your program is scanned for all variable/function declarations and those relationships are saved in the [lexical environment](https://www.ecma-international.org/ecma-262/6.0/#sec-lexical-environments). Your code maintains its original formatting and structure while variable/function declarations are accessible via lexical environment.

#### Hoisting Functions:

- <strong>Function Declarations </strong> are hoisted to the very top of the program. They can be called in the code prior to actual declaration. The example below logs without error:

![function declaration hoisting example](https://thepracticaldev.s3.amazonaws.com/i/w8hhxyjhe5bz10xkmimv.png)<figcaption>function declarations hoisted to top of program</figcaption>

- <strong>Function Expressions</strong> are not completely hoisted in the program. Instead, only the declaration will be hoisted because it is recognized as a variable (hint: `var` keyword). The actual assignment of the variable's value (in this case a function) is not hoisted. In the example below, you'll first get an error stating that expression is not a function. That is because the assignment was not hoisted - only the declaration. The second call of `expression()` works, because the program has parsed through the program ad reached the assignment of the function to `var expression`. 


![function expression hoisting example](https://thepracticaldev.s3.amazonaws.com/i/po8v2c981sxgd1vad71u.png)<figcaption>declaration is hoisted, but not assignment of function value</figcaption>


#### Hoisting Variables:
Variables are hoisted to the top of their scope (local or global). Variables declared with `var` are hoisted slightly differently that variables declared with `const` or `let`. 

- <strong>var Variables</strong> are hoisted, initialized, but assigned value of `undefined`. Similar to function expressions only the declaration is hoisted, not the actual assignment of the variable's value. The code below demonstrates how `var` variables are hoisted, initialized with a value of `undefined`, and then reassigned their value once the program reaches the value assignment.  

![var variable hoisting example](https://thepracticaldev.s3.amazonaws.com/i/wsk4p0t4xvubmpilz092.png)<figcaption>hoisted, initialized, assigned undefined</figcaption>

- <strong>let/const Variables</strong> are a little more tricky. These variables are hoisted, but remain uninitialized until they are evaluated. Unlike the `var` variables which are hoisted <em>and</em> initialized with a value of `undefined`, `let`/`const` variables are hoisted, but not initialized at all. That means they're sitting in the lexical environment uninitialized. Attempting to access a variable that is uninitialized throws a reference error. Once the program is in execution and reaches the variable declaration, your `let`/`const` variable will be initialized. It will either be initialized with a value (if assigned in the declaration line) or with `undefined` until a value assignment is reached later on in the code. 

This can be rather confusing at first, so let's take a look at the example below. You'll see that first an error is thrown because while the variable exists in the lexical environment, it remains uninitialized until the program reaches the line of variable declaration. Line 11 the variable gets initialized, but is assigned a value of `undefined` because there is no value assignment. Line 13 the variable is assigned a value which overwrites previous value of `undefined`. 

![let const variable examples](https://thepracticaldev.s3.amazonaws.com/i/cpjrrsvusgwfpkk09mhh.png)<figcaption>hoisted, but initialized & assigned value once declaration is reached in code</figcaption>

Take a look at the example below which showcases `let`/`var` variables and their hoisting differences side by side:

![compare contrast var let hoisting](https://thepracticaldev.s3.amazonaws.com/i/owisglbs4w99o24gue89.png)<figcaption>note the difference in how var is hoisted and initialized and let is not</figcaption>





#### Key Takeaways!

- Variable declarations are hoisted, while variable definitions are not.
- Function declarations are hoisted, while function expressions are not.
- Variables with `var` are hoisted, initialized, and assigned value of `undefined`
- Variables with `let`/`const` are hoisted, but remain uninitialized until their variable declaration code is reached. Then, they are either assigned `undefined` or a value depending if value assignment exists.
- It is helpful to declare your variables at the top of the function scope. This way, it is clear where variables are coming from and easier to identify their scope. 
- Declare and initialize your variables before use to avoid bugs which stem from incorrect hoisting assumptions.