# What is hoisting in JavaScript?

> Learn what hoisting means in JavaScript: how the engine moves declarations into memory, and why function declarations can be called before they are defined.

Author: Flavio Copes | Published: 2020-06-16 | Canonical: https://flaviocopes.com/javascript-hoisting/

[JavaScript](https://flaviocopes.com/javascript/) before executing your code parses it, and adds to its own memory every function and variable declarations it finds, and holds them in memory. This is called **hoisting**.

We have some different behaviors for function declarations and function expressions.

With function declarations, we can call a function before it's defined, and our code will work. In the other cases, we'll have errors.

A general rule of thumb is to always define functions, variables, objects and classes before using them, to avoid surprises.

Suppose we have a function:

```js
function bark() {
  alert('wof!')
}
```

Due to hoisting, we can technically invoke `bark()` before it is declared:

```js
bark()
function bark() {
  alert('wof!')
}
```

With functions, this only happens for **function declarations**. Like in the case above.

**Not with function expressions**.

This is a function expression:

```js
bark()
var bark = function() {
  alert('wof!')
}
```

In this case, the `var` declaration is hoisted and initialized with `undefined` as a value, something like this:

```js
var bark = undefined
bark()
bark = function() {
  alert('wof!')
}
```

Running this code will give you a  `TypeError: bark is not a function` error.

`const` and `let` declarations are hoisted, too, but they are not initialized to undefined like `var`.

```js
const bark = function() {
  alert('wof!')
}
```

or

```js
let bark = function bark() {
  alert('wof!')
}
```

In this case, if you invoke `bark()` before declaring it, it will give you a `ReferenceError: Cannot access 'bark' before initialization` error.

The same will happen for any other expression that assigns an object or class to a variable

Class declarations work like `let` and `const` declarations: they are hoisted, but not initialized, and using a class before its declaration will give a `ReferenceError: <Class> is not defined` error.
