-
Notifications
You must be signed in to change notification settings - Fork 1
08. Cómo funciona JavaScript
El navegador interpreta el archivo HTML y cuando termina de transformarlo al DOM (Document Object Model - representación que hace el navegador de un documento HTML) se dispara el evento DOMContentLoaded el cual indica que el documento está disponible para ser manipulado. Todo script que carguemos en nuestra página tiene un llamado y una ejecución.
-
asyncRealiza la petición de forma asíncrona. Pero cuando esta acaba, detiene la carga del DOM para ejecutar el script. -
deferRealiza la petición de forma asíncrona. Pero ejecuta el script cuando ya se cargó todo el documento - scripts embebidos: el browser carga linea a linea, cuando encuentra un código entre scripts detiene la carga para ejecutar el script.
Hay que tener en cuenta que cuando carga una página y se encuentra un script a ejecutar toda la carga se detiene. Por eso se recomienda agregar tus scripts justo antes de cerrar el body para que todo el documento esté disponible.
- Recibe código fuente
- Parsea el código y produce un Abstract Syntax Tree (AST)
- Se compila a bytecode y empieza a ejecutarse
- Se optimiza a machine code y se reemplaza el código base
-> JavaScript Source Code - to:
-> Parser - to:
-> Abstract Syntax Tree - to:
--Optimize--
-> Interpreter - to:
-> bytecode - through 'Profiling data procesor' to: //In Bytecode start to run
-> Optimizing Compiler - to:
-> Optimized code //Generate Machine Code
-> Código fuente
-> Tokens //Parser
-> Abstract Syntax Tree
Un SyntaxError es lanzado cuando el motor de javascript se encuentra con parte de código que no forman parte de la sintaxis del lenguaje al momento de analizar código (parser).
- Parsing es 15-25% del proceso de ejecución
- La mayoría del JS en una página nunca se ejecuta entonces el Bundling y Code Splitting son muy importantes
- Encuentra errores de sintaxis
- Crea el AST
- Construye scopes
- Doble de rápido que el eager parser
- No crea el AST
- Construye los scopes parcialmente
var helloWorld = "Hello" + " World";
var answer = 6 * 7;[
{
"type": "Keyword",
"value": "var"
},
{
"type": "Identifier",
"value": "helloWorld"
},
{
"type": "Punctuator",
"value": "="
},
{
"type": "String",
"value": "\"Hello\""
},
{
"type": "Punctuator",
"value": "+"
},
{
"type": "String",
"value": "\" World\""
},
{
"type": "Punctuator",
"value": ";"
},
{
"type": "Keyword",
"value": "var"
},
{
"type": "Identifier",
"value": "answer"
},
{
"type": "Punctuator",
"value": "="
},
{
"type": "Numeric",
"value": "6"
},
{
"type": "Punctuator",
"value": "*"
},
{
"type": "Numeric",
"value": "7"
},
{
"type": "Punctuator",
"value": ";"
}
]El AST es un gráfo (estructura en forma de árbol). Donde vamos a tener una raíz que será nuestro programa y lo vamos a ir descomponiendo en partes, todo esto lo vamos a poder hacer siguiendo los tokens que produce el parser, esto se usa en muchas cosas, no solo para ejecutar un programa javascript, también lo usamos para transformar código de una forma a otra que es como lo que hace babel o prettier. Pruebalo Aquí
Se usa en:
- Javascript Engine
- Bundlers: Webpack, Rollup, Parcel
- Transpilers: Babel
- Linters: ESLint, Prettify
- Type Checkers: TypeScript, Flow
- Syntax Highlighters
Crear regla eslint:
const pi = 3.1415;
const halft_pi = 1.356;
// Variables constantes
// Variables que guarden un número
// El nombre de la variable tiene que estar en UPPER CASEexport default function (context) {
return {
VariableDeclaration(node) {
// Tipo de variable const
// asegurarnos que el valor es un número
if (node.kind === "const" && typeof declaration.init.value === "number") {
const declaration = node.declarations[0];
if (declaration.id.name !== declaration.id.name.toUpperCase()) {
context.report({
node: declaration.id,
message: "El nombre de la constante debe estar en Mayúsculas",
//Opcional, autoarreglar el error
fix: function (fixer) {
return fixer.replaceText(declaration.id,
declaration.id.name.toUpperCase());
}
})
}
}
}
}
};- Recibe código fuente
- Parsea el código y produce un Abstract Syntax Tree (AST)
- Se compila a bytecode y se ejecuta
- Se optimiza a machine code y se reemplaza el código base
- Código parecido a assembly
- Portatil
- Ejecutado por una virtual machine
- Binario
- Instrucciones especificas a una arquitectura o procesador
Para aprovechar los motores de JavaScript:
- Las funciones reciban los mismos tipos de datos
- Las estructuras de datos (Arreglos y Objectos) mantengan la misma forma.
Así el motor de JS podrá optimizar el código que se ejecuta constantemente enviándolo de ByteCode a OptimizedCode.
function add(a, b) {
return a + b;
}
for (let i = 0; i < 1000; i++) {
add(i, i);
}Se ira ejecutando el código hasta que esté preparado para ser optimizado, convirtiéndose en una Hot Function.
add(1,"hola");Romperá la optimización y seguira ejecutando bytecode

Hace que js parezca ser multi-hilo a pesar de que corre en un solo proceso.
Js se organiza usando las siguientes estructuras de datos:
- Stack (apilar): Apila de forma organizada las diferentes instrucciones que se llaman. Lleva así un rastro de dónde está el programa, en que punto de ejecución nos encontramos.
- Memory Heap: Guarda información de las variables y del scope de manera desorganizada.
- Task Queue (cola de tareas): Aquí se agregan las tares que ya están listas para pasar al stack y ser ejecutadas. El stack debe estar vacío para que esto suceda.
- Schedule Tasks (tareas programadas): Aquí se agregan a la cola, las tareas programadas para su ejecución.
- MicroTask Queue: Aquí se agregan las promesas. Esta Queue es la que tiene mayor prioridad.
El Event Loop es un loop que está ejecutando todo el tiempo y pasa periódicamente revisando las queues y el stack moviendo tareas entre estas dos estructuras.
function moreAsync() {
console.log('start');
setTimeout(() => console.log('setTimeout'), 0);
Promise.resolve('Promise 1').then(msg => console.log(msg));
Promise.resolve('Promise 2').then(msg => console.log(msg));
console.log('end');
}
moreAsync();
