2  F2. JavaScript y TypeScript: lo esencial para este libro

Solo las piezas del lenguaje que el libro usa — nada de relleno

NotaEn una frase

El JavaScript/TypeScript mínimo que necesitas: variables, funciones, objetos, arrays, módulos y async/await. Si vienes “de la era de la AI” y nunca aprendiste esto en orden, este capítulo es tu base — todo lo demás del libro se apoya aquí.

2.1 El problema

Sabes pedirle a una AI “hazme un componente” — pero cuando el código que devuelve usa .map(), ...spread, async/await o import, ¿entiendes qué hace cada pieza? Sin esa base, eres copiloto sin saber volar: la AI escribe y tú no puedes revisarla.

Un bucle repite una acción por cada elemento o hasta cumplir una condición: for task in tasks hace algo con cada tarea. map y filter son bucles disfrazados de funciones — transforman/filtran colecciones sin for explícito.

return hace dos cosas a la vez: devuelve el resultado Y termina la función — lo que esté debajo nunca corre. return task = “aquí está el plato, salgo de la cocina”.

Asíncrono = empezar algo sin esperar sentado a que termine: pides la pizza (async) y sigues trabajando; cuando llega, te avisan. Lo opuesto a síncrono (esperar parado). Vital cuando la espera es larga: red, disco, bases de datos.

Un módulo es un archivo de código que exporta cosas para que otros archivos las importen. Es la unidad de organización: en vez de un archivo gigante, el código vive en módulos con responsabilidad propia.

Este capítulo no es un curso de JavaScript — es el inventario exacto de piezas que el libro usa, cada una con un ejemplo que puedes correr en la consola del navegador ahora mismo (F12 → Console).

La terminal (consola, línea de comandos) es la interfaz de texto con el sistema operativo: escribes comandos, lees resultados. Es como hablarle a la computadora por cartas en vez de señalar con el mouse.

2.2 Cómo lo resuelve un equipo

En un equipo real nadie memoriza el lenguaje entero — se domina el 20% que se usa el 95% del tiempo, y el resto se busca. Ese 20% en este libro es:

variables → objetos/arrays → funciones → módulos → async → tipos TS

Cada pieza abajo tiene: qué es, un ejemplo mínimo, y por qué la vas a usar en backend.

2.3 Conceptos nuevos

  • U const/let — variables (usa const por defecto).
  • U Objetos y arrays — las estructuras que viajan en JSON.
  • U .map() / .filter() — transformar colecciones sin loops.
  • U import/export — módulos ES.
  • U async/await — esperar operaciones lentas sin bloquear.
  • TS Type annotations — el “JS con etiquetas” que es TypeScript.

2.4 Las piezas, una por una

2.4.1 Variables y objetos

const title = "deploy";           // const: no se reasigna
let count = 0;                    // let: sí puede cambiar
count = count + 1;

const task = {                    // objeto = el JSON que ya viste
  id: 1,
  title: "deploy",
  done: false,
};
task.title;                       // "deploy" — acceso por punto
const { title: t } = task;        // destructuring: sacar campos

Por qué importa: un endpoint devuelve objetos; un body es un objeto. Si lees { id, title, done } como “una tarea”, ya tienes el 80% del JSON del libro.

2.4.2 Arrays y transformaciones

const tasks = [
  { id: 1, title: "a", done: true },
  { id: 2, title: "b", done: false },
];

tasks.map((t) => t.title);          // ["a","b"] — transforma cada uno
tasks.filter((t) => !t.done);       // [{id:2…}] — deja solo los que cumplen
tasks.find((t) => t.id === 2);      // la tarea o undefined

Por qué importa: GET /tasks devuelve un array; tu backend hará .find()/filter() constantemente antes de que exista la base de datos.

Una base de datos es el programa que guarda datos de forma permanente y los responde rápido. Relacional (Postgres): tablas con relaciones. No relacional: documentos, clave-valor, grafos — cada una para una forma de dato distinta.

2.4.3 Funciones

// tres formas de la misma función
function add(a, b) { return a + b; }
const add2 = (a, b) => a + b;              // arrow function
const add3 = async (a, b) => a + b;        // async (devuelve Promise)

Por qué importa: un handler es literalmente una función que recibe el request y devuelve la respuesta. Ya sabes handlers — no lo llamabas así.

2.4.4 Módulos

// services/tasks.js
export function createTask(title) { … }

// index.js
import { createTask } from "./services/tasks.js";

Por qué importa: el Cap. 7 organiza el backend en archivos — import es cómo se conectan.

2.4.5 async/await

const res = await fetch("/tasks");   // pausa aquí hasta que responde
const tasks = await res.json();      // otra pausa: parsear el body

async marca que la función puede pausar; await espera el resultado de algo lento (red, disco). Por qué importa: todo lo que tarda (llamar APIs, leer la BD) es async — en los tres lenguajes del libro.

2.4.6 TypeScript: JS + etiquetas

interface Task { id: number; title: string; done: boolean }

function createTask(title: string): Task {
  return { id: 1, title, done: false };
}

Por qué importa: TypeScript es JS con etiquetas de tipo que el editor chequea antes de correr. Las etiquetas desaparecen al ejecutar — son andamiaje, no runtime (el Cap. 4 vuelve a esto).

El runtime es el motor que ejecuta tu código: Node.js es el runtime de JavaScript fuera del navegador; CPython es el de Python; Go compila a binario y el runtime va empaquetado dentro. Es “quien corre” lo que escribiste.

Los roles agrupan permisos: viewer lee, editor escribe, admin gestiona. RBAC = el permiso depende del rol que tienes en ese recurso — puedes ser admin de un equipo y viewer de otro.

2.5 La explicación visual

flowchart LR
  A["const task = {…}"] --> B["objeto en memoria"]
  B -->|"JSON.stringify"| C["texto JSON<br/>viaja por HTTP"]
  C -->|"JSON.parse"| D["objeto otra vez<br/>(en el servidor)"]

Objeto ↔︎ JSON ↔︎ objeto: ese viaje es toda la comunicación frontend↔︎backend.

Un objeto es una colección de datos con nombre: {name: "Ana", age: 30} — cada dato es una propiedad (clave → valor). Python los llama dict, Go los arma con struct, TS con objetos/interface.

Quiero un repaso práctico de JavaScript moderno SOLO de estos temas:
const/let, objetos, arrays con map/filter/find, arrow functions,
import/export de ES modules, async/await, y qué agrega TypeScript encima.
Para cada tema: un ejemplo de 3-5 líneas que pueda pegar en la consola del
navegador, qué imprime, y un uso real en una API. No me des un curso
completo — solo estas piezas.

2.6 Errores comunes

  • Confundir map con forEach: .map() devuelve un array nuevo (útil); .forEach() solo itera (no devuelve nada).
  • await fuera de async: error de sintaxis — el await necesita vivir dentro de una función async (o top-level en módulos modernos).
  • Creer que los tipos TS existen en runtime: interface se evapora al compilar — no valida nada que llegue por red (ese es el trabajo del Cap. 4).

Un compilador traduce código a otra forma: TypeScript → JavaScript (transpila), Go → binario (compila). Atrapa errores antes de ejecutar. tsc, esbuild, go build son compiladores.

  • const no es inmutable: const task = {} no se reasigna, pero task.done = true sí muta el contenido.

2.7 Buenas prácticas

  • const por defecto, let solo cuando reasignas — menos sorpresas.
  • Destructuring al recibir objetos: const { title } = req.body es más legible que req.body.title.
  • Una exportación por concepto: funciones pequeñas con nombre claro > un archivo gigante.
  • Aprende a leer antes que a escribir: si entiendes .map().filter(), ya lees el 70% del código frontend y backend real.

2.8 Ejercicio

En la consola del navegador (F12):

  1. Crea un array de 3 tareas y usa .filter() para quedarte con las no hechas; .map() para sacar solo los títulos.
  2. Escribe JSON.stringify(tuArray) y luego JSON.parse() del resultado — verifica que obtienes el mismo array.

Un array es una colección ordenada de elementos accedidos por posición: ["a","b","c"][0] es "a" (se cuenta desde 0). Python las llama listas, Go slices — misma idea, distinto acento.

Serializar es convertir un objeto en memoria a texto viajero (JSON.stringify); parsear/deserializar es el viaje de vuelta (JSON.parse). Todo lo que cruza la red o la BD pasa por este par.

2.9 Mini reto

Sin ejecutarlo: ¿qué devuelve esto y por qué?

const tasks = [{ id: 1, done: false }, { id: 2, done: true }];
tasks.filter(t => t.done).map(t => t.id);

Pista: encadena las dos operaciones — primero filtra, luego transforma.

Ejercicio 1.

const tasks = [
  { id: 1, title: "a", done: true },
  { id: 2, title: "b", done: false },
  { id: 3, title: "c", done: false },
];
tasks.filter(t => !t.done);        // [{id:2…},{id:3…}]
tasks.map(t => t.title);           // ["a","b","c"]

Ejercicio 2. JSON.stringify produce texto ('[{"id":1,…}]'); JSON.parse lo convierte de vuelta a objetos — el mismo array. Ese ida y vuelta es literalmente lo que hacen fetch y tu futuro servidor.

Mini reto. [2]: filter deja solo {id:2, done:true}, luego map extrae su id. Encadenar filter().map() es el patrón más común del mundo para transformar colecciones — lo verás cientos de veces.

2.10 Vocabulario técnico del capítulo

Una variable es una caja con nombre donde guardas un valor: let total = 42 guarda el 42 bajo el nombre total. Puedes leerla y cambiarla después (total = 50). const = caja que no se puede reemplazar.

Una función es una receta reutilizable: recibe ingredientes (parámetros), hace pasos y devuelve un plato (return). La escribes una vez y la llamas mil veces: add(2, 3) → 5.

Una clase es el molde de un objeto: define qué datos y qué métodos tiene. class Task es el molde; new Task() es una instancia concreta. Go no tiene clases — usa struct + métodos sueltos.

Un string es texto entre comillas: "hola". El nombre viene de “cadena de caracteres” — una secuencia de letras. Todo lo que llega de un formulario o una URL llega como string, aunque parezca número.

Un booleano es un valor de dos estados: true o false. Es el resultado de toda comparación (age > 18) y lo que los if evalúan. Nombrado por George Boole, el matemático de la lógica.

La memoria RAM es el escritorio de trabajo del programa: rápida, pero se borra al apagar. Los datos que deben sobrevivir van a disco o a la base de datos. Por eso let tasks = [] pierde todo al reiniciar.

Un deploy es poner tu código a correr en el servidor: copiar la imagen, iniciar el proceso, verificar que responde. El objetivo es que sea aburrido — automático, repetible, con rollback.

Una traza sigue un request a través de todo el sistema: entró por el gateway → llamó auth → consultó la BD → tardó 340ms en la query. Cuando algo anda lento, la traza dice exactamente dónde.

2.11 Lo que deberías saber hacer ahora