Tribalyte Technologies Tribalyte Technologies
  • Inicio
  • Misión y visión
  • Nuestros expertos
  • Nuestras soluciones
  • Casos de éxito
  • Blog
  • Contáctanos
  • Únete al equipo
Tribalyte Technologies Tribalyte Technologies
  • Inicio
  • Misión y visión
  • Nuestros expertos
  • Nuestras soluciones
  • Casos de éxito
  • Blog
  • Contáctanos
  • Únete al equipo
Jun 05

Entendiendo cómo funciona el motor de JavaScript

  • junio 5, 2020
  • Monica Rebordinos
  • No Comments
  • Desarrollo de software, Tecnologías

Es importante entender cómo funciona JavaScript por dentro; saber qué ocurre en sus tripas nos permite crear un código optimizado y rápido de ejecución. Y no sólo eso, sino que también nos ayuda a entender la naturaleza de los errores que vemos por consola.

Es posible que alguna vez hayas perdido incontable tiempo de trabajo tratando de averiguar por qué una función se ejecuta antes que otra y tal vez hasta hayas puesto algo tan feo como esto:

setTimeout( doSomething, 1000);

Y pensaste que se ejecutaría un segundo más tarde, pero no lo hizo hasta mucho después… los tiempos de ejecución en JavaScript son misteriosos, ¿o tal vez no? Empecemos con un poco de historia.

Comienzos de la web y la irrupción de JavaScript

En la década de los noventa las conexiones a Internet no eran como las de ahora, la velocidad era de 56kbps y veíamos páginas web totalmente estáticas y sin capacidad de aportar soluciones de negocio empresariales más allá de información de texto plano, imágenes y animaciones vía GIF.

Tribalyte_blog_motor_javascript1

* Esta es una de las primeras páginas web creadas en España: trataba sobre razas de perros

JavaScript nace en 1995 creado por Brendan Eich, trabajador por aquel entonces de Netscape, como proyecto interno para dotar a la web de dinamismo y velocidad. 

Gracias al éxito y amplia aceptación de este lenguaje de scripting del lado del cliente, Microsoft lanzó en Internet Explorer su propio lenguaje “como un fork” de JavaScript, bautizado con el nombre de JScript, partiendo de JavaScript pero con algunas variaciones e implementaciones añadidas como, por ejemplo, el manejo de fechas para el “efecto 2000“, entre otros.

Tener distintas aproximaciones para un mismo fin se convirtió en un caos para la industria y por lo tanto para los usuarios. Algunas páginas web no funcionaban bien en todos los navegadores y para subsanar este comportamiento era necesario que programar varios códigos específicos con el impacto en costes extra que esto acarrea al equipo de desarrollo.

Para evitar una guerra de tecnologías finalmente Netscape envía la especificación de JavaScript a ECMA International para su estandarización. La primera versión oficial sería ECMAScript 1 y se publicó en 1997, con varias revisiones posteriores hasta ES6 o ES2015, momento en el que el estándar se va actualizando anualmente.

La siguiente infografía es muy interesante para ver de manera visual la evolución histórica de los navegadores, su ciclo de vida y en qué momento introducen cada tecnología.

Tribalyte_blog_javascript_infografia_evolucion_javascript

* Fuente [http://www.evolutionoftheweb.com/?hl=es]

Después de este breve repaso por la historia nos vamos centrar en el funcionamiento del motor de JavaScript. Este conocimiento es importante a la hora de depurar nuestras aplicaciones y para entender errores y comportamientos en la ejecución de nuestro código.

El motor de JavaScript

Para interpretar el lenguaje los navegadores incluyen un motor de JavaScript, siendo algunos de los más conocidos los siguientes:

  • SpiderMonkey (Firefox)
  • V8 usado navegadores basados en Chromium (Chrome, Microsoft Edge, Opera) y en Node.js y Deno.
  • JavaScriptCore usado en navegadores basados en Webkit (Safari).
  • Carakan (versiones antiguas de Opera).
  • Chakra intérprete de JScript (Internet Explorer).

JavaScript es un lenguaje single-thread, es decir, tiene solo un hilo de ejecución, por lo que las tareas se van ejecutando secuencialmente.

El lanzamiento en 2008 del motor V8 como proyecto open source, desarrollado por Google, supuso una gran mejora en los motores de JS al crear una combinación de intérprete y compilador. Actualmente el resto de motores modernos utilizan esta técnica, JIT (Just In Time compiler).

Tribalyte_blog_javascript_linea_temporal

¿Cómo funciona?

El compilador traduce el código fuente a bytecode de la manera más rápida posible y, este bytecode es ejecutado por el intérprete. El sistema también cuenta con un «Profiler» que analiza las operaciones e identifica el código que se puede optimizar para mejorar el rendimiento. Luego se reemplazan las secciones de bytecode por el código optimizado. Esto implica que la velocidad de ejecución del código JavaScript mejora gradualmente mientras se ejecuta.

A continuación, vamos a desglosar algunos elementos fundamentales que necesitamos comprender para poder entender el funcionamiento interno de JavaScript.

  • Call stack
  • Memory Heap
  • Event loop
  • Callback queue
  • Web APIs
  • Hoisting

Call Stack y Memory Heap

JavaScript tiene un solo subproceso con un contexto de ejecución global, esto significa que JavaScript maneja una sola pila de llamadas (Call Stack) y un Memory Heap, que hace referencia a la parte de la memoria no estructurada donde se guardan los objetos y funciones. Las funciones del Call Stack se procesarán en el orden en que se llama, comúnmente conocido como Last-In, First-Out (LIFO).

Veamos como funciona con un ejemplo muy sencillo utilizando las Dev Tools de Chrome. Primero creamos un ejemplo de código que realiza un cálculo con sumas y restas simples y ponemos un punto de parada para poder avanzar en la ejecución paso a paso.
ribalyte_blog_javascript_dev_tools

Primero llama a la función «calculate» y la añade a la pila de ejecución; dentro de esta función se hace uso de una nueva función «addFive», y la añade al «Call Stack» encima de «calculate». Así mismo ocurre con «subtractTwo» que se coloca encima de las dos anteriores. Posteriormente, según se van ejecutando, se va vaciando en orden inverso a como se han añadido.

Web APIs

Hacen referencia a las APIs integradas en el navegador, están creadas con JavaScript y facilitan la  implementación de algunas funcionalidades. Algunas de las interfaces más conocidas son:

  • DOM (Document Object Model)
  • XMLHttpRequest
  • Geolocalización
  • Funciones de timer (setTimeout, setInterval)

Event loop y Callback queue

Para manejar tareas que requieren de un mayor tiempo de procesamiento o tardan en devolver una respuesta, como por ejemplo, una llamada al servidor, se hace uso de los callbacks, funciones que se llaman cuando finalmente se recibe el resultado de la operación.

Los callbacks se van encolando en lo que llamamos “Callback Queue” en espera a ser pasados a la pila de ejecución.

El Event Loop es un observador que se encarga de escuchar si hay tareas pendientes en el Callback Queue y las añade al Call Stack cuando este se vacía.

El ejemplo más sencillo es la función setTimeout, recibe dos parámetros: el primero es la función callback a ejecutar y el segundo es el tiempo de espera hasta que es añadido a la cola; si hay más elementos en la cola se añadirán cuando se hayan ejecutado, el segundo parámetro indica el tiempo mínimo de espera por lo que no garantiza cuando se va ejecutar la tarea.

Tribalyte_blog_javascript_diagrama_navegador

* Diagrama de funcionamiento del navegador

 

Veamos un pequeño ejemplo de cómo funciona el Event Loop, utilizando de nuevo la consola dentro del inspector web de Chrome, utilizando setTimeout e imprimiendo un mensaje en la pantalla.
Tribalyte_blog_javascript_infografia_consola_even_loop

 

Empieza a ejecutarse siguiendo los siguientes pasos:

  1. La primera línea de código es un console.log que se añade directamente al Call Stack
  2. La segunda línea se refiere a un setTimeout por lo que pasa la ejecución a las Web APIs que esperaran 2s antes de enviar la sentencia al Callback Queue
  3. La tercera línea se refiere a otro setTimeout pero en este caso el tiempo es 0 por lo que directamente se añade al Callback Queue
  4. La cuarta línea es otro console.log que se añade directamente al Call Stack
  5. La quinta línea se refiere a un setTimeout por lo que pasa la ejecución a las Web APIs que esperaran 1s antes de enviarlo el console.log al Callback Queue
  6. La sexta línea es otro console.log que se añade directamente al Call Stack

Tribalyte_blog_javascript_call_stack

Hoisting

El término Hoisting se refiere al comportamiento de JavaScript por el que las declaraciones de variables y funciones son asignadas en memoria durante la fase de compilación, esto significa que se puede utilizar una variable / función antes de que sea declarada.

Tribalyte_blog_javascript_hoisting_var

Por el contrario cuando se declaran variables con let y const aparece un error, ya que al contrario que var, solo están disponibles el scope en el que son declaradas y el hoisting no realiza la asignación de la variable a undefined.

Tribalyte_blog_javascript_hoisting_let
Con el modo “estricto” de JavaScript no se permite que se utilicen variables antes de ser declaradas; en cualquier caso, es una buena práctica declarar las variables al inicio del scope.

Esperamos que esta entrada os haya servido de ayuda para comprender un poquito mejor el funcionamiento interno de uno de los lenguajes de programación más populares. ¡Hasta pronto!

Artículos Relacionados:

  • realidad_aumentada_blog_tribalyteRealidad Aumentada usando Unity y Vuforia: ejemplo práctico
  • revisión códigoLa importancia de la revisión de código como parte de la política de calidad de la organización
  • El método científico aplicado al desarrollo de softwareEl método científico aplicado al desarrollo de software
  • ¿Qué son las APIs REST?¿Qué son las APIs REST?
  • ¿Cómo eliges la próxima tarea a acometer?¿Cómo eliges la próxima tarea a acometer?
  • Facebook
  • Twitter
  • LinkedIn
  • E-Mail

About The Author

Mónica es desarrolladora de software en Tribalyte, especializada en tecnologías móviles. Posee una amplia experiencia en el desarrollo de aplicaciones nativas Android (Java) e iOS (Objective-C / Swift). Amante de las nuevas tecnologías, las buenas prácticas de desarrollo, el testing y mantenerse siempre formada.

Leave a reply Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

ELIGE UNA CATEGORÍA

  • Blockchain
  • Consejos tecnológicos
  • Desarrollo de aplicaciones
  • Desarrollo de software
  • Sistema embebido
  • Tecnologías

Suscríbete a nuestra newsletter y entérate de las últimas tendencias tecnológicas.

Una compañía dedicada al desarrollo y la mejora de plataformas tecnológicas globales.

SOCIOS

Contacto

Glorieta de Quevedo 8 6º2
28015 Madrid (ESPAÑA)
Phone: +34 910 177 514 E-Mail: contact@tribalyte.com Web: www.tribalyte.com

AYUDA

  • Política de privacidad
  • Política de calidad
  • Términos de uso

CERTIFICACIONES

INTERNACIONALIZACIÓN

  Tribalyte     Technologies S.L. en   el Marco del Programa de Iniciación a la Exportación del Prog. ICEXNEXT, ha contado con el apoyo del ICEX y con la cofinanciación del fondo Europeo FEDER. La finalidad de este apoyo es contribuir al desarrollo Internacional de la empresa y de su entorno.
Esta página web utiliza cookies para mejorar su experiencia de usuario y para recabar estadísticas anónimas de uso. Aceptar Más información