Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 188 additions & 0 deletions book/conceptos fundamentales/hoisting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Comportamiento Hoisting

> Hoisting cae en uno de esos conceptos que traducido al espa帽ol simplemente no se siente bien.

Antes de entender el comportamiento hoisting propio del motor de JavaScript, es necesario tener claro que todo comportamiento puede derivar en un "resultado inesperado" si no se conoce el funcionamiento interno de la declaraci贸n y la asignaci贸n de variables en relaci贸n con su propio alcance de acuerdo al `谩mbito/scope` en el que se encuentre.

En realidad JavaScript no es raro o inesperado, es s贸lo adaptable e incre铆ble. Si se conocen las perillas adecuadas se puede controlar su comportamiento y eso es algo destacable de su motor. Escarbemos un poco m谩s profundo jugando con la consola:

```
console.log(no);
```

`ReferenceError: no is not defined`

```
no;
```

`ReferenceError: no is not defined`

## Asignaci贸n

Una variable se puede usar antes de haber sido declarada:

```
si = 1;
```

`1`

```
console.log(si);
```

`1`

## Declaraci贸n

Es v谩lido que una variable se declare despu茅s de haber sido usada.

```
var si;

console.log(si);
```

`1`

```
var tampoco;

console.log(tampoco);
```

`undefined`

## Declararaci贸n y Asignaci贸n

```
var hmm = 'pensando...';

console.log(hmm);
```

`'pensando...'`

```
var con = 'libros';

console.log(con, hay)
```

`ReferenceError: hay is not defined`

```
var hay = 'progreso'

console.log('Con ' + con + ' hay ' + hay)
```

`Con libros hay progreso`

## Comportamiento Hoisting

Hoisting no se trata de mover manualmente todas las declaraciones de variables al inicio del ambiente actual. Esto es algo que el motor de JavaScript hace por nosotros, se puede pensar en esta transformaci贸n como el resultado de un comportamiento interno propio de JavaScript.

Hoisting es m谩s f谩cil de masticar con un ejemplo:

```javascript
elevarExperimento();

function elevarExperimento() {
invocarOtraFuncion();

// Variable en el 谩mbito local a la funci贸n.
var gato = 'Schr枚dinger.';

console.log(gato);
}

function invocarOtraFuncion() {
console.log('Por alguna raz贸n algui茅n me invoc贸.');
}
```

el cuerpo de la funci贸n `elevarExperimento()` de manera autom谩tica se interpreta como:

```javascript
function elevarExperimento() {
var gato;

invocarOtraFuncion();

gato = 'Schr枚dinger';

console.log(gato);
}
```

Una forma sencilla de alterar el comportamiento de hoisting se logra s贸lo con introducir una variable en el 谩mbito global:

```javascript
// Variable en el 谩mbito global.
var gato = 'No estoy ni muerto ni vivo, soy un perro que est谩 fuera de la caja.';

function elevarExperimento() {
console.log(gato); // undefined
invocarOtraFuncion();
var gato = 'Schr枚dinger';
console.log(gato);
}

function invocarOtraFuncion() {
console.log('Por alguna raz贸n algui茅n me invoc贸.');
}

elevarExperimento();
```

en el primer `console.log()` esperabamos ver el valor global, pero no sucede porque internamente el motor de JavaScript interpreta que debe elevar la declaraci贸n de `var gato` al inicio de la funci贸n:

```javascript
function elevarExperimento() {
var gato;

console.log(gato); // undefined
invocarOtraFuncion();

gato = 'Schr枚dinger';

console.log(gato);
}
```

Una manera bastante interesante de alterar el comportamiento "hoisting" del motor de JavaScript se puede comprobar pasando la variable del 谩mbito global como parametro de la funci贸n, por ejemplo:

```javascript
var gato = 'No estoy ni muerto ni vivo, soy un perro que est谩 fuera de la caja.';

function elevarExperimento(gato) {
console.log(gato); // 'No estoy ni ... fuera de la caja.'
invocarOtraFuncion();
var gato = 'Schr枚dinger';
console.log(gato);
}

function invocarOtraFuncion() {
console.log('Por alguna raz贸n algui茅n me invoc贸.');
}

elevarExperimento(gato);
```

Por esta raz贸n la mayor铆a de desarrolladores recomiendan brindar legibilidad al c贸digo declararando las variables al principio de su 谩mbito, esto tambi茅n permite detectar `comportamientos desconocidos` o errores con mayor facilidad.

```javascript
function soyUnDesarrolladorCivilizado() {
var nombre = 'Hattori Hanz艒';
var posicion = 'Ninja';
var habilidad = 'Invisibilidad';
var extension = 'Katana';

liderarUnClan();
unirUnaNacion();
}
```

En el fondo este tema es mucho m谩s extenso, si se juega y escarba un poco m谩s se pueden descubrir m谩s `comportamientos desconocidos`, que suena mucho mejor que `raro` o `inesperado`.