loading...
Cover image for Entendiendo el hoisting

Entendiendo el hoisting

gugadev profile image Gus Garzaki ・3 min read

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, ya que necesitaremos entender lo que es un contexto de ejecución.

Analicemos el siguiente código:

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í:

var language = 'English'

changeLanguage()

function changeLanguage() {
  language = 'Spanish'
}

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

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:

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:

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

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

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.

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

En el hosting será:

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:

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. Es un plugin para ejecutar directamente código JavaScript en tu editor a medida que lo escribes. Muy útil para pruebas rápidas.

Posted on by:

gugadev profile

Gus Garzaki

@gugadev

Developer. Researcher. Student.

Discussion

markdown guide
 

Master Guz, pienso que el resultado de esto

goodMorning()
goodEvening()

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

Seria esto

function goodMorning() {
  console.log('Buenos días')
}

goodMorning()

var goodEvening;

goodEvening()

console.log('Buenas noches') //result