Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Profesional
de JavaScript
Richard B. Kaufman López
@sparragus
Introducción
Senior
Junior
Senior
El duro camino lleno
de experiencia
¿Qué forma a
un profesional?
No-fundamentos
Cómo funciona
No
Fundamentos
Getters, Setters
Proxies
Generadores
Cómo funciona
Herencia prototipal
Event loop
Entornos de
Programación
Mucho
Constantemente
Mejores
prácticas
Probamos nuestro
código
Ética
Entregar a tiempo
No hacer daño
Experiencia
No se puede enseñar
Está en ti
Perseverancia
Cómo funciona JavaScript
head body
title h1 P
#text
DOMContentLoaded
El Navegador
Scripts externos
o embebido
<html>
<head>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async
src="https://googletagmanager.com/gtag/js?id=U-123456-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
</script>
</head>
<body><!-- ... --></body>
</html>
https://developers.google.com/analytics/devguides/collection/gtagjs/
Scripts embebidos
HTML
Script Execution
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
</script>
<body>
<script>
let formEl = document.querySelector("#loginForm");
formEl.addEventListener("submit", function (event) {
// ...
});
</script>
TypeError
formEl.addEventListener("submit", function (event) {
// ...
});
💥
</script>
<script>
let formEl = document.querySelector("#loginForm");
formEl.addEventListener("submit", function (event) {
// ...
});
</script>
</body>
Scripts externos
HTML
Script Fetching
Script Execution
<head>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async
src="https://googletagmanager.com/gtag/js?id=U-123456-1"></script>
</head>
<body><!-- ... --></body>
Orden de ejecución (async)
HTML
Script Fetching
Script Execution
Script Fetching
Script Execution
<body>
<script async src="/hugeScript.js"></script>
<script async src="/smallScript.js"></script>
</body>
Scripts externos (defer)
HTML
Script Fetching
Script Execution
<body>
<script defer src="/index.js"></script>
<!-- A bunch of html -->
</body>
Cómo funciona JavaScript
Parsers y el
Abstract Syntax Tree
JavaScript es interpretado
La web no es como antes
JavaScript
Engines
SpiderMonkey - Firefox
JavaScriptCore - Safari
Chakra - Edge
¿Qué hace un JS Engine?
Interpreter bytecode
Deoptimize
Optimize
da ta
fili ng
ro
+P
Optimizing Optimized
compiler code
JavaScript Abstract
source code parser Syntax Tree
Interpreter bytecode
Deoptimize
Optimize
da ta
fili ng
ro
+P
Optimizing Optimized
compiler code
¿Qué hace un parser?
Parser
Código Abstract
fuente Tokens Syntax Tree
¿Qué hace un parser?
Un SyntaxError es lanzado cuando el
motor de JavaScript
Parserse encuentra con
partes de código que no forman parte
Código Abstract
de la sintaxis delTokens
fuente lenguaje al momento
Syntax Tree
analizar el código.
https://developer.mozilla.org/es/docs/Web/JavaScript/
Referencia/Objetos_globales/SyntaxError
Google dice:
Se usa en:
● JavaScript Engine
● Bundlers: Webpack, Rollup, Parcel
● Transpilers: Babel
● Linters: ESLint, Prettify
● Type Checkers: TypeScript, Flow
● Syntax Highlighters
Demo - AST
Demo - ESLint Rule
Cómo funciona JavaScript
JavaScript Engine:
Interpreter, Compiler
& Código Optimizado
¿Qué hace un JS Engine?
Interpreter bytecode
Deoptimize
Optimize
da ta
fili ng
ro
+P
Optimizing Optimized
compiler code
Interpreter vs
Optimizing Compiler
Interpreter bytecode
Deoptimize
Optimize
d ata
fil ing
o
+ Pr
}
return a + b;
🔥
for (let i = 0; i < 1000; i++) {
add(i, i);
}
V8
Interpreter bytecode
Deoptimize
Optimize
d ata
fil ing
o
+ Pr
}
return a + b;
❄
for (let i = 0; i < 1000; i++) {
add(i, i);
}
add(1, “uno”);
V8
Interpreter bytecode
Deoptimize
Optimize
d ata
fil ing
o
+ Pr
Interpreter bytecode
Optimize
Somewhat
Baseline optimized code
Deoptimize
+ Profiling data
Interpreter bytecode
Deoptimize
Optimize
Somewhat
SimpleJIT optimized code
+ Profiling data
© Mathias Bynens
JavaScriptCore
LLInt bytecode
Somewhat
Baseline optimized code
Optimize
Deoptimize
Mostly
DFG optimized code
© Mathias Bynens
Cómo funciona JavaScript
Event loop
Stack y Memory Heap
getMovies
renderList
main
Stack
Stack
Push
main
Stack
Push
renderList
main main
Stack
Push
getMovies
renderList renderList
getMovies
getMovies
getMovies
Scope {
getMovies
...
}
renderList
main
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello();
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello();
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello();
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello();
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
hello
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
} console.log
function world() {
console.log("World")
hello
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
hello
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
world
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
} console.log
function world() {
console.log("World")
world
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
world
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello(); main
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello();
world();
} (anonymous)
main();
Programa
function hello () {
console.log("Hello")
}
function world() {
console.log("World")
}
function main() {
hello();
world();
}
main();
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
setTimeout
}
asyncHelloWorld
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
console.log
}
asyncHelloWorld
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
asyncHelloWorld();
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
console.log
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
asyncHelloWorld();
(anonymous)
Programa Asíncrono
function asyncHelloWorld () {
setTimeout(() => {
console.log("hello")
}, 1000);
console.log("world!");
}
asyncHelloWorld();
Task Queue
Scheduled Tasks
setTimeout
asyncHelloWorld
Task Queue
(anonymous)
Stack
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Queue
Task Queue
Scheduled Tasks
setTimeout
asyncHelloWorld
Task Queue
(anonymous)
Stack
Task Queue
Scheduled Tasks
setTimeout(anonymous, 1000)
asyncHelloWorld
Task Queue
(anonymous)
Stack
Task Queue
Scheduled Tasks
setTimeout(anonymous, 1000)
Task Queue
Stack
Task Queue
Scheduled Tasks
setTimeout(anonymous, 1000)
Task Queue
Stack
Task Queue
Scheduled Tasks
Task Queue
anonymous
Stack
Task Queue
Scheduled Tasks
Task Queue
(anonymous)
Stack
Event loop
Scheduled Tasks
Task Queue
anonymous
Task Queue
(anonymous)
setTimeout(anonymous, 0)
asyncHelloWorld
Task Queue
(anonymous)
asyncHelloWorld
Task Queue
(anonymous) anonymous
Task Queue
(anonymous) anonymous
Task Queue
anonymous
Task Queue
(anonymous)
Task Queue
asyncHelloWorld
Task Queue
(anonymous)
setTimeout(anonymous, 30)
asyncHelloWorld
Task Queue
(anonymous) anonymous
Task Queue
Task Queue
anonymous anonymous
Task Queue
anonymous anonymous
Task Queue
anonymous
Task Queue
anonymous
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();
Promesas
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")
}
Output:
> Start
moreAsync(); > End
> Promise 1
> Promise 2
> setTimeout
Event loop (iv)
Scheduled Tasks
setTimeout(anonymous, 0)
Microtasks Queue
(Promise 1) (Promise 2)
moreAsync
Task Queue
anonymous
Microtasks Queue
(Promise 1) (Promise 2)
Task Queue
anonymous anonymous
Microtasks Queue
(Promise 1) (Promise 2)
Task Queue
anonymous
Microtasks Queue
(Promise 2)
Task Queue
(Promise 1) anonymous
Microtasks Queue
(Promise 2)
Task Queue
anonymous
Microtasks Queue
Task Queue
(Promise 2) anonymous
Microtasks Queue
Task Queue
anonymous
Microtasks Queue
Task Queue
anonymous
Microtasks Queue
Task Queue
Qué es un
patrón de diseño
Una solución para
un problema dentro
de un contexto.
Una solución para un problema
dentro de un contexto.
e r Pa t t e r n
Observ
Ejemplos
Every Layout
¿Cómo acomodar elementos?
Nombre
Contexto
Problema
Patrón de diseño
Ejemplos
every-layout.dev/layouts/stack
Media Queries
¿Cómo acomodar la información
para diferentes tamaños de pantalla?
mediaqueri.es
Patrones
de React
Publicado en 1995.
Jeff Atwood
blog.codinghorror.com/head-first-design-patterns
Conclusión
Categorías de
patrones de diseño
Categorías
● Abstract Factory
● Builder
● Factory Method
● Prototype
● Singleton
Builder
(Constructor)
$("<input />")
.attr({ "type": "email", "id":"email"})
.appendTo("#login-form");
Patrones estructurales
● Adapter
● Bridge
● Composite
● Decorator
● Façade
● Flyweight
● Proxy
// Cómo jQuery usa el Adapter
// IE <=11+
let inputEl = document.createElement("input")
inputEl.value = "priority-shipping";
inputEl.type = "radio";
console.log(inputEl.value) // undefined
// Con jQuery
let $input = $("<input />");
$input.val("priority-shipping");
$input.attr({ type: "radio" });
console.log($input.val()) // priority-shipping
Patrones de
comportamiento
Gestionan algoritmos y
responsabilidades entre objetos.
Patrones de
comportamiento
● Chain of ● Memento
Responsibility
● Observer
● Command
● State
● Interpreter
● Strategy
● Iterator
● Template Method
● Mediator
● Visitor
// Cómo jQuery usa el Composite
// Un solo elemento
$("#submit-button").addClass("big-text");
$("#hero-heading").addClass("big-text");
// Muchos elementos
$("button").addClass("big-text");
$(".title").addClass("big-text");
$("h1").addClass("big-text");
Patrones de Diseño -
Singleton
Descripción y
Caso de Uso
Singleton
(Creacional)
Singleton
- instance: Singleton
- Singleton( )
+ getInstance( ): Singleton
Estructura
Nombre de la clase
Singleton
privados
- instance: Singleton } propiedades
- Singleton( )
} métodos
público + getInstance( ): Singleton
Subrayado = Estático
Implementación (TypeScript)
class Database {
private static instance: Database;
private constructor() {
// init
}
return Database.instance;
}
class Database {
constructor() {...}
public connect(url) {
// Implementation code
}
}
export default new Database();
Una analogía
El gobierno de tú país.
'use strict';
Descripción
Imaginate que...
Estructura
Observer
(Comportamiento)
Observer / Subscriber
Observer
(Comportamiento)
DocumentTitleDisplay
+ update()
BitcoinPriceNotifier
- observers: Observer[]
+ subscribe(Observer)
+ unsubscribe(Observer) MainDisplay
+ notify(price: number)
+ update()
GraphDisplay
+ update()
Patrones de Diseño -
Observer
Casos de uso
Redux
store.subscribe(function() {...});
store.dispatch({ type: ‘INCREMENT’ });
store.getState();
el estado
Modifica el estado...
los observers
...y notifica a los
interesados
un observer
unsubscribe
EventEmitter (Node.js)
EventEmitter
(Node.js)
Descripción
y Casos de Uso
Imaginate
que...
+ cost()
+ cost()
MacBookPro512GB3 + cost()MacBookPro512GB8 + cost() MacBookPro1TB4G + cost()MacBookPro512GB1
2GBRAM2.6GHZ GBRAM2.4GHZ BRAM2.6GHZ 6GBRAM2.6GHZ
+ cost()
+ cost()
MacBookPro512GB3 + cost()MacBookPro512GB8 + cost() MacBookPro1TB4G + cost()MacBookPro512GB1
2GBRAM2.6GHZ GBRAM2.4GHZ BRAM2.6GHZ 6GBRAM2.6GHZ
BlueMacBookPro51
BlueMacBookPro1T BlueMacBookPro1T BlueMacBookPro1T
2GB4GBRAM2.6GH
B32GBRAM2.6GHZ B8GBRAM2.4GHZ B16GBRAM2.6GHZ
Z
+ cost()BlueMacBookPro51 + cost()BlueMacBookPro51 + cost() BlueMacBookPro1T + cost()BlueMacBookPro51
2GB32GBRAM2.6G 2GB8GBRAM2.4GH 2GB16GBRAM2.6G
B4GBRAM2.6GHZ
HZ Z HZ
+ cost() + cost() + cost() + cost()
😭
class MacBookPro1TB32GBRAM26GHZ {
constructor(){ ... }
cost() {
return 3199;
}
}
class MacBookPro1TB16GBRAM26GHZ {
constructor(){ ... }
cost() {
return 2999;
}
}
“Hola buen dev.
Lo que sucede es que
la RAM bajó de precio
entonces hay que
actualizar los precios.”
Una entidad de software
(clase, módulo, función, etc.)
debe quedar abierta para su
extensión, pero cerrada
para su modificación
Estructura
Decorator
(Estructural)
https://en.wikipedia.org/wiki/Decorator_pattern
Decorator
(Estructural)
🙈
https://en.wikipedia.org/wiki/Decorator_pattern
The JavaScript Way
(Monkey patching)
class MacbookPro {
constructor() { this.memory = 8; }
cost() { return 2399; }
}
console.log(macbook.cost())
// 2999
The JavaScript Way
Closures
Herencia prototipal
Middleware
ECMAScript Decorators (Stage 2)
Patrones de Diseño -
Decorator
Casos de uso
Lodash.memoize
Lodash.memoize
función decorada