JavaScript es uno de los lenguajes más populares y el favorito para la Web. Los Devs no tenemos que lidiar con compiladores para poder correr nuestro código JavaScript. El navegador compila en tiempo de ejecución, pasando de código a Bytecode. En este post me enfocaré en V8 Engine, desarrollado por Google y basado en Chromium, este es el mejor motor que existe y es utilizado por Browsers como Chrome, Edge, Brave, entre otros.
El V8 Engine
Te comente que el Engine transforma nuestro código JavaScript a Bytecode para que el Browser lo pueda interpretar.
Entorno Global
Una vez que llega un archivo de JavaScript al navegador y es ejecutado, el engine generará un entorno global que hace tres cosas muy importantes:
-
Objeto global llamado window. Si vamos a la consola podemos ver que window nos devuelve la API con todos los métodos que tenemos disponibles.
Por ejemplo podríamos ejecutar window.console.log("Hello Chrome V8); y exactamente exactamente igual.
-
Generará un contexto llamado this. En un contexto global this es igual a window.
this === window;
// true
- Ambiente de ejecución.
Una vez generado este contexto global comienza el contexto de ejecución (Execution context) donde corre el código de JavaScript utilizando un Stack de tareas, a continuación el motor ejecutara los siguientes procesos:
- Parser
- AST
- Interprete
- Profiler y compiler
Parser
Se genera un parseo del documento completo mediante palabras claves como function, var, etc. Existen dos tipos de parsers, el parser y el pre-parser. Con la finalidad de reducir el tiempo de carga.
El parser se encarga del código que se debe correr en el momento y el pre-parser aquel que se utilizará después. Con ejecutar después me refiero a tareas que se ejecutarán, por ejemplo, luego de una acción del usuario (click en un botón).
AST
El Abstract syntaxt tree (AST) se crea a partir de los nodos que genera el parser y es una estructura de árbol que representa tu código sintácticamente. Podemos utilizar la página AST Explorer y ver como este árbol es generado.
También podríamos generar JSX y ver cómo responde el árbol.
Una vez que el Bytecode es generado el AST es eliminado para liberar memoria.
Profiler y compiler
El profiler monitorea el código para optimizarlo. El compiler optimiza ese código y genera machine code (lenguaje binario). En esta etapa, y por la intención de optimizar el código, también genera errores como el Hoisting.
Analiza el siguiente código:
console.log(name); // undefined
var name = "Gaspar";
console.log(name); // "Gaspar"
En el primer console.log name es undefined, esto porque está haciendo referencia a una variable que no ha sido declarada. El motor de JavaScript sabrá que una variable name va a existir por lo que la declarara antes y le asignará undefined. Es como hacer lo siguiente:
var name = undefined;
console.log(name); // undefined
name = "Gaspar";
console.log(name); // "Gaspar"
Algo parecido ocurre con function, dónde podemos llamar una funcion antes de ser declarada y no necesariamente después:
hello("Gaspar"); // "Hello Gaspar"
function hello(name) {
console.log(`Hello ${name}`);
}
hello("Pep"); // "Hello Pep"
A esto se le denomina Hoisting.
Take it easy. El código permanecerá igual, es solo una interpretación del engine de JavaScript que intenta optimizar nuestro código. Pero esto puede causar errores y resultados no esperados ya que el motor declara las variables y funciones en un scope superior, Global o de función.
Esto lo podremos contrarrestar si en lugar de utilizar var utilizamos let o const. Mira el siguiente código:
console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name = "Gaspar";
Como puedes ver si utilizamos let o const para definir nuestras variables evitaremos el Hoisting y nuestras variables no se inicializará como undefined.
Podemos evitar el Hoisting en las funciones si utilizamos las arrow functions:
hello("Gaspar"); // ReferenceError: hello is not defined
const hello = (name) => {
console.log(`Hello ${name}`);
};
Conclusiones
Ahora ya sabes el camino que tiene que seguir nuestro archivo JavaScript para poder ser interpretado y ejecutado dentro del navegador, también ya sabes que es el Hoisting y cómo evitarlo. Aún hay muchas cosas dentro del funcionamiento de Chrome V8, esto solo fue una breve introducción pero eres libre de revisar la documentación de V8 y también el GitHub de V8, es open source.