# JS Tip of the Day: Hoisting

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-hoisting/643162>\
**Category:** web dev\
**Created:** [March 5, 2020, 12:23pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-hoisting/643162 "2020-03-05T12:23:49Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [March 5, 2020, 12:23pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-hoisting/643162/1 "2020-03-05T12:23:49Z")

</div>

**Hoisting**  
Version: ES2015 (let, const class)  
Level: Intermediate

Hoisting is a term to describe how declarations in JavaScript appear to get moved or “hoisted” to the top of their scope. Hoisted variables are able to be recognized in code before their declarations. There are 3 kinds of hoisting:

- Variables with values initialized
- Variables with default values initialized
- Variables with uninitialized values

Variable declarations that are hoisted with their values initialized only occurs with `function` declarations (including generator and `async` variations). This means that not only can the function name variable be recognized before its declaration, but it will also already have its function value. The result is that, during code execution, you can call a function declaration even before its declaration has been reached.

```javascript
logTriangleSides(); // 3

function logTriangleSides () {
    console.log(3);
}

```

The effects of hoisting allows the code to appear as though it has been written as:

```javascript
function logTriangleSides () {
    console.log(3);
}

logTriangleSides(); // 3

```

`var` declarations are declarations that are hoisted but initialized with a default value. The default values for such declarations (those that can have default values, i.e. `var` and `let`) is `undefined`. If you try to access a `var`-declared variable before its declaration, you’ll be able to access the variable, but you will get its default value of `undefined`, even if the variable was given an initializer value in its declaration. It’s defined value doesn’t get assigned until execution reaches the declaration.

```javascript
console.log(squareSides); // undefined
var squareSides = 4;
console.log(squareSides); // 4

```

Hoisting in the context of `var` variables makes the code appear to be written as:

```javascript
var squareSides = undefined;
console.log(squareSides); // undefined
squareSides = 4;
console.log(squareSides); // 4

```

Declarations that are uninitialized before their declarations are reached include `let`, `const`, and `class`. Unlike the other forms of hoisting seen earlier with `function` and `var`, you’re not allowed to access these variables at all prior to their declarations.

```javascript
console.log(pentagonSides); // ReferenceError (pentagon has secrets!)
let pentagonSides = 5;

```

Hoisting here translates to something similar to:

```javascript
let pentagonSides; // <-- but no initialization, not even undefined
console.log(pentagonSides); // ReferenceError
pentagonSides = 5;

```

Any attempt to access an uninitialized variable results in an error.

You may then ask yourself, is hoisting really involved if you can’t access the variable before its declaration? The answer is yes when you consider the following example:

```javascript
let pentagonSides = 'five';
{
    console.log(pentagonSides); // ReferenceError
    let pentagonSides = 5;
}

```

Here there are two scopes, the top-level scope where the first `pentagonSides` is defined with a value of ‘five’, and then a block-level scope below it with a call to `console.log` followed by the original `pentagonSides` declaration from before. Even though the first `pentagonSides` variable would have been initialized and available before the call to `console.log`, an error is still thrown because the `pentagonSides` that call is recognizing is the uninitialized version declared below it; declared below, but hoisted (though uninitialized) above.

```javascript
let pentagonSides = 'five';
{
    let pentagonSides; // <-- uninitialized
    console.log(pentagonSides); // ReferenceError
    pentagonSides = 5;
}

```

This form of hoisting creates what is referred to as the “temporal dead zone”, or TDZ. The temporal dead zone is the area in the scope above `let`, `const`, and `class` declarations where those variables cannot be accessed. This applies even though there might be a variable of the same name accessible from a higher scope.

More info:

- [Hoisting on MDN](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
- [let on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)
