Behind the scenes ¿Como funciona realmente Javascript?

Wikipedia define a JavaScript como un lenguaje de programación interpretado, basado en prototipos, imperativo, débilmente tipado y dinámico.
Muy bonita definición, pero esto no nos dice mucho sobre cómo funciona realmente Javascript. En este post te lo voy a contar (re Taringa)


Cuando escribimos nuestro código Javascript y queremos correrlo, pasan muchas cosas de las cuales no nos enteramos.
En primer lugar sabemos que nuestro código se ejecuta en un ambiente determinado, este ambiente puede ser un navegador web tal como Google Chrome, Mozilla Firefox, Opera, etc (aunque hoy también existe la posibilidad de utilizar Javascript para desarrollo en backend gracias a NodeJs). Ahora bien, cada uno de estos navegadores tiene un Javascript Engine o Motor Javascript (Google Chrome tiene su V8 Engine, el cual también es usado por NodeJs, Mozilla Firefox tiene su SpiderMonkey Engine, etc etc). ¿Y esto que es? te preguntarás.
El Javascript Engine es un programita que básicamente interpreta nuestro código JavaScript y ejecuta un script acorde a las instrucciones dadas.
Yendo un poco más al núcleo de lo que pasa en el Javascript Engine, nuestro código es parseado por un Parser que va leyendo nuestro código línea por línea y chequeando la sintaxis del mismo. Esto significa que este Parser conoce las reglas de javascript y sabe como debe estar escrito nuestro código para que sea válido. Si hay uno o más errores un error es lanzado y se detiene la ejecución, pero si está todo ok el Parser produce una estructura de datos llamada Abstract Syntax Tree (AST) que luego es traducida a código máquina el cual si puede ser directamente ejecutado por la máquina.


El Javascript Engine se compone de:

El componente Memory Heap el cual básicamente se encarga de la asignación de la memoria
La pila de llamada a funciones (Call Stack): Recordemos que Javascript es un lenguaje single-threaded, es decir puede hacer una sola cosa a la vez. Volviendo a la Call Stack, la misma es una estructura de datos que registra básicamente en qué parte del programa estamos, se podría decir que es una lista TODO de invocaciones a funciones. Si entramos en una función, la colocamos en la parte superior de la pila. Cuando esta función retorna algo o finaliza, sale de la parte superior de la pila. Eso es todo lo que la pila puede hacer. Vamos con un ejemplo:

Tenemos dos funciones, firstThing y SecondThing la cual también invoca a la primera. Ponemos un breakpoint en el llamado de la segunda función y vemos que pasa:

Vemos en el Call Stack que en primer lugar se apila una función anonymous, si damos step en el debugger:

La función secondThing es llamada y como vimos antes esta función invoca a la función firstThing:

Ahora parados en la función firstThing vemos que la misma devuelve algo y por ende, debe salir de la pila:

Por último, ahora ya parados en la función secondThing, vemos que la misma devuelve algo y finaliza y al finalizar sale de la Call Stack y volvemos al punto inicial:

Entender esto nos permite dar una idea del funcionamiento de JavaScript y de la importancia de no cometer errores como pueden ser el mal-utilizar funciones de manera recursiva, lo que provocaría el famoso Overflowing como en el siguiente ejemplo:

¿Te imaginas que va a pasar? La función secondThing invoca a la función firstThing, y esta invoca a secondThing que invoca a firstThing, estas llamadas recursivas terminan por llenar la Call Stack y se lanza el siguiente error:

Con toda esta información espero que ya puedas comprender un poco más lo que pasa cuando ejecutamos nuestro Javascript. Si aún seguís sin entender tranquilo, todavía queda mucho por contarte pero eso vendrá en los siguientes posts así que estate atento.

Adeus !

Mandanos tus sugerencias

Ayudanos con ideas para los artículos de este blog a contacto@somospnt.com

¡Seguínos en nuestras redes sociales para enterarte de los últimos posts!