====== 04 - JavaScript ====== **JavaScript** es el lenguaje del navegador y, con **Node** (tema 05), también del servidor. Sintácticamente desciende de C como Java: el control de flujo, los operadores y los comentarios se escriben igual. Se asume lo aprendido en **Programación** (bucles, condicionales, funciones, POO); este tema cubre la **sintaxis del lenguaje** y sus particularidades: tipado dinámico, funciones flexibles y objetos literales. ===== 1. El lenguaje de un vistazo ===== const RATE = 0.2; // constante let subtotal = 0; // variable subtotal += 42; for (const tag of tags) { // for...of itera colecciones console.log(tag); // consola del navegador o de Node } * ''const'' y ''let'' en lugar de ''var''; ''const'' para todo lo que no cambie. * ''console.log()'' sustituye a ''System.out.println()''. * Las **clases** se escriben casi como en Java (''constructor'', ''this''); en este módulo se usarán siempre en ficheros **TypeScript** (tema 06). ===== 2. Tipado dinámico ===== No hay tipos en la declaración: el tipo lo tiene el **valor** y puede cambiar al reasignar. 42 // number: enteros y decimales sin distinción "Código" // string, con comillas simples o dobles true null // sin valor, a propósito undefined // aún no tiene valor El lenguaje **convierte tipos** sin aviso (coerción): "3" + 1 // "31": el número se convierte a texto "3" * 2 // 6: el texto se convierte a número Number("3") // 3: conversión explícita Por eso, la comparación siempre con ''==='': 0 == "" // true: == compara tras convertir tipos 0 === "" // false: === exige el mismo tipo * En una condición actúan como ''false'' los valores *falsy*: ''0'', ''""'', ''null'', ''undefined'' y ''NaN''; el resto son *truthy*. ===== 3. Cadenas: template literals ===== const author = "Robert C. Martin"; const title = `El taller de ${author}`; const multiline = `Código limpio Robert C. Martin`; * Las **comillas invertidas** delimitan un ''template literal'' y la sintaxis ''${...}'' interpola cualquier expresión. * Aportan saltos de línea reales sin ''\n''. ===== 4. Objetos ===== El objeto literal agrupa datos como un mapa ''clave → valor'', con anidamiento libre: const book = { id: 42, title: "Código limpio", author: { name: "Robert C. Martin" }, }; book.title // "Código limpio" book.author.name // encadenado book["title"] // acceso con corchetes book?.author?.name // ?. no falla aunque falte la ruta book.price ?? "no consta" // ?? valor por omisión si es null o undefined * ''?.'' corta el acceso en cuanto una propiedad no existe, en lugar de lanzar el error a mitad de la expresión. * ''??'' aporta un valor solo cuando el resultado es ''null'' o ''undefined'' (no con ''0'' o ''""''). ===== 5. Arrays y métodos ===== const books = [ { id: 42, title: "Código limpio", genre: "ensayo", price: 12 }, { id: 43, title: "Refactoring", genre: "ensayo", price: 14 }, { id: 44, title: "La peregrina", genre: "novela", price: 9 }, ]; books.push({ id: 45, title: "El bibliotecario", genre: "novela", price: 8 }); books.length; // 4 const novels = books.filter(b => b.genre === "novela"); // selecciona const prices = books.map(b => b.price); // transforma const total = prices.reduce((sum, p) => sum + p, 0); // acumula books.find(b => b.id === 42); // busca el primero * ''map'', ''filter'', ''find'' y ''reduce'' operan sobre colecciones sin bucles manuales: es la programación funcional ya estudiada en **Programación**, con la sintaxis del lenguaje. ===== 6. Funciones ===== function discount(price, percent) { // declaración clásica return price * (1 - percent / 100); } const iva = (price) => price * 0.21; // arrow function books.map(function (b) { return b.title; }); // función como argumento books.map(b => b.title); // lo mismo, en flecha * Las funciones son **valores**: se asignan a variables, se guardan en objetos y se pasan como argumentos (''callback''). * La **función flecha** ''(parámetros) => expresión'' devuelve la expresión sin ''return''; es la forma habitual en los métodos de arrays y en el código async. ===== 7. Desestructuración y spread ===== const { title, author } = book; // extrae propiedades a variables const [first] = tags; // extrae elementos const withTags = { ...book, tags: ["craft"] }; // copia el objeto y añade const all = [...essays, ...novels]; // une arrays function describe({ title, price }) { // extrae en los parámetros return `${title}: ${price} €`; } * El **spread** (''...elementos'') copia y combina estructuras sin mutar las originales. ===== 8. Módulos ===== // src/price.js export const RATE = 0.2; export function discount(price, percent) { return price * (1 - percent / 100); } export default function summary(books) { return `${books.length} títulos`; } // src/main.js import summary, { discount, RATE } from "./price.js"; * ''export'' publica y ''import'' consume; ''export default'' define el valor por omisión del módulo, que se importa sin llaves. * Con Node y con TypeScript la ruta del import incluye la extensión ''.js''. La consola del navegador (F12) y el REPL de ''node'' permiten probar fragmentos sin proyecto. Cuando algo falla en ejecución, el mensaje indica el fichero y la línea: los errores de JavaScript se ven en ejecución, no al compilar.