Entendiendo el hoisting
Tags: javascript, backtothebasics
Published: 2019-04-07 18:59:10

En esta oportunidad, analizaremos un comportamiento que sucede a cada instante cuando programamos en Javascript, pero que no podemos verlo; un concepto abstracto, imperceptible. Algo que pasa "detrás de escenas" y que es parte del lenguaje. Hoy hablaremos de **hoisting**.

Antes de entender qué es _hosting_ recomiendo leer mi post anterior: [This y el contexto de ejecución](https://dev.to/stuxdev/javascript-internals-this-y-el-contexto-de-ejecucion-5foj), ya que necesitaremos entender lo que es un _contexto de ejecución_.

Analicemos el siguiente código:

```javascript
var name = 'stuxdev'

whoami() // <- Im stuxdev

function whoami() {
  console.log('Im ', name)
}
```

Si la función `whoami` es escrita al final de nuestro código, ¿cómo es que puede invocarse antes de que se defina? ¿Cuál es el sentido de esto?

La respuesta es: el contexto de ejecución y sus _fases_.

## Fases del contexto de ejecución

La creación de un contexto de ejecución se divide en dos fases: _creación_ y _ejecución_. Veamos en qué consisten estas fases.


### Fase de creación

En esta fase ocurren tres cosas importantes:

- Se crea el objeto global `window`.
- Se crea el objeto especial `this` para representar el contexto de ejecución actual.
- Se crean **espacios en memoria** para reservar en memoria las **declaraciones** de variables y funciones.

Es esta última frase justamente donde se produce lo que conocemos como _hoisting_. Pero, ¿qué sucede durante el _hoisting_?

**Hosting**

Es simplemente un nombre que sirve para identificar el proceso de colocar las declaraciones de variables y funciones en memoria dentro de un contexto de ejecución. Es decir, todas las declaraciones se ponen en memoria en la parte más alta del stack.

Si en un contexto léxico tenemos un código así:

```javascript
var language = 'English'

changeLanguage()

function changeLanguage() {
  language = 'Spanish'
}
```

Cuando ocurre el _hoisting_, en memoria es traducido de la siguiente manera:

```javascript
var language;

function changeLanguage() {
  language = 'Spanish';
}

changeLanguage();
```

Aquí nos damos cuenta de un par de cosas interesantes. La primera, es que cuando ocurre el _hoisting_, solo se mueven las declaraciones de variables, **mas no se inicializan**:

```javascript
var language; // <- no hay inicialización
```

Lo segundo, es que las _function statements_ son puestas enteras, mientras que las _function expressions_, al ser parte de una declaración de variable, solo se mueve la parte de declaración. Para que se entienda, veamos el siguiente ejemplo:

```javascript
function foo() { ... }
var bar = function bar() { ... }
```

Cuando ocurra el hoisting, se convertirá en lo siguiente:

```javascript
function foo() { ... }
var bar;
```

## Fase de ejecución

En esta fase se lleva a cabo la ejecución del código, sentencia a sentencia. En esta parte es precisamente en donde se identifican en memoria todas las declaraciones de variables y funciones y se les asigna su contenido. En el caso particular de las funciones como asignaciones, en tiempo de ejecución **no tendrán un valor hasta que el intérprete llegue a la línea** en donde se le asigna un valor.

```javascript
console.log('¡Soy un ninja JS!')
var sayHi = function sayHi() {
  ...
}
```

En el _hosting_ será:

```javascript
var sayHi;
console.log('¡Soy un ninja JS!')
```

---

## Quiz time!

Veamos un código de ejemplo que nos sirva como ejercicio para poner en práctica lo que se ha tratado a lo largo del artículo.

Teniendo como base este código:

```javascript
goodMorning()
goodEvening()

function goodMorning() {
  console.log('Buenos días')
}
var goodEvening = function goodEvening () {
  console.log('Buenas noches')
}
```

👽 ¿Cuál es la salida del código?

> 🚫¡No se vale usar internet!

Deja la respuesta en los comentarios. Actualizaré el post para explicar la respuesta 😉

---

## ⭐ Plus

Si usas Visual Studio Code como editor, puedes instalar [Quokka](https://quokkajs.com/). Es un plugin para ejecutar directamente código JavaScript en tu editor a medida que lo escribes. Muy útil para pruebas rápidas.