Volver
Ctrl+Space
◑
Copiar
Descargar
Restaurar
Ejecutar
Ctrl+Enter
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Funciones en JS — Ejemplo 4</title> <style> body { font-family: Arial, sans-serif; padding: 20px; background: #fff; max-width: 680px; } h3 { margin: 20px 0 8px; font-size: 15px; color: #333; } table { border-collapse: collapse; width: 100%; margin-bottom: 14px; } th { background: #F7DF1E; color: #333; padding: 8px 12px; text-align: left; font-size: 13px; } td { padding: 8px 12px; border-bottom: 1px solid #eee; font-size: 13px; font-family: monospace; } .bloque { background: #f9f9f9; border-left: 4px solid #F7DF1E; padding: 10px 14px; margin: 8px 0; border-radius: 0 6px 6px 0; font-size: 14px; } .label { font-size: 11px; color: #888; font-weight: bold; margin-bottom: 4px; text-transform: uppercase; } ul { margin: 0; padding-left: 18px; font-family: monospace; font-size: 14px; } li { margin: 3px 0; } .ok { color: #059669; font-weight: bold; } </style> </head> <body> <h2>Funciones de orden superior y composición</h2> <h3>Funciones que reciben funciones (callbacks)</h3> <table id="tabla-callback"></table> <h3>Funciones que retornan funciones</h3> <table id="tabla-retorna"></table> <h3>Composición de funciones</h3> <div class="bloque"><div class="label">pipeline de transformaciones</div><ul id="lista-comp"></ul></div> <h3>Caso completo — sistema de reportes</h3> <div class="bloque"><div class="label">reporte configurable con funciones</div><div id="reporte"></div></div> <script> // Funciones en JavaScript - Ejemplo 4: Funciones de orden superior // ── Funciones que reciben funciones ──────────────────────────────────── function aplicarA(array, fn) { const resultado = []; for (const item of array) resultado.push(fn(item)); return resultado; } function filtrarCon(array, predicado) { const resultado = []; for (const item of array) { if (predicado(item)) resultado.push(item); } return resultado; } function reducirCon(array, fn, inicial) { let acc = inicial; for (const item of array) acc = fn(acc, item); return acc; } const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const tablaC = document.getElementById("tabla-callback"); tablaC.innerHTML = `<tr><th>Llamada</th><th>Resultado</th></tr>`; [ [`aplicarA(nums, n => n * 2)`, `[${aplicarA(nums, n => n * 2).join(", ")}]`], [`aplicarA(nums, n => n * n)`, `[${aplicarA(nums, n => n * n).join(", ")}]`], [`filtrarCon(nums, n => n % 2===0)`,`[${filtrarCon(nums, n => n % 2 === 0).join(", ")}]`], [`filtrarCon(nums, n => n > 5)`, `[${filtrarCon(nums, n => n > 5).join(", ")}]`], [`reducirCon(nums, (a,n)=>a+n, 0)`, String(reducirCon(nums, (a, n) => a + n, 0))], [`reducirCon(nums, (a,n)=>a*n, 1)`, String(reducirCon(nums, (a, n) => a * n, 1))], ].forEach(([llamada, res]) => { tablaC.innerHTML += `<tr><td>${llamada}</td><td>${res}</td></tr>`; }); // ── Funciones que retornan funciones ─────────────────────────────────── function crearMultiplicador(factor) { return n => n * factor; } function crearSumador(base) { return n => n + base; } function crearValidador(min, max) { return valor => valor >= min && valor <= max; } function crearFormateador(prefijo, sufijo = "") { return valor => `${prefijo}${valor}${sufijo}`; } const doble = crearMultiplicador(2); const triple = crearMultiplicador(3); const mas10 = crearSumador(10); const esEdadValida = crearValidador(13, 120); const formatoPeso = crearFormateador("$"); const formatoPct = crearFormateador("", "%"); const tablaR = document.getElementById("tabla-retorna"); tablaR.innerHTML = `<tr><th>Función creada</th><th>Llamada</th><th>Resultado</th></tr>`; [ ["doble = crearMultiplicador(2)", "doble(7)", String(doble(7))], ["triple = crearMultiplicador(3)", "triple(7)", String(triple(7))], ["mas10 = crearSumador(10)", "mas10(25)", String(mas10(25))], ["esEdadValida(13, 120)", "esEdadValida(25)", String(esEdadValida(25))], ["esEdadValida(13, 120)", "esEdadValida(10)", String(esEdadValida(10))], ["formatoPeso = crearFormateador('$')", "formatoPeso(1250)", formatoPeso(1250)], ["formatoPct = crearFormateador('','%')","formatoPct(21)", formatoPct(21)], ].forEach(([fn, llamada, res]) => { tablaR.innerHTML += `<tr><td>${fn}</td><td>${llamada}</td><td>${res}</td></tr>`; }); // ── Composición ──────────────────────────────────────────────────────── // Aplicar una serie de funciones en secuencia function pipeline(valor, ...fns) { let resultado = valor; for (const fn of fns) resultado = fn(resultado); return resultado; } const procesarNombre = nombre => pipeline( nombre, s => s.trim(), s => s.toLowerCase(), s => s.split(" ").map(p => p[0].toUpperCase() + p.slice(1)).join(" ") ); const calcularPrecioFinal = precio => pipeline( precio, p => p * 0.85, // descuento 15% p => p * 1.21, // IVA 21% p => Math.round(p * 100) / 100 // redondear a 2 decimales ); const listaComp = document.getElementById("lista-comp"); [ [`procesarNombre(" ana GARCÍA ")`, procesarNombre(" ana GARCÍA ")], [`procesarNombre("JUAN pablo pérez")`, procesarNombre("JUAN pablo pérez")], [`calcularPrecioFinal(1000)`, `$${calcularPrecioFinal(1000)}`], [`calcularPrecioFinal(500)`, `$${calcularPrecioFinal(500)}`], ].forEach(([expr, res]) => { const li = document.createElement("li"); li.textContent = `${expr} → ${res}`; listaComp.appendChild(li); }); // ── Sistema de reportes ──────────────────────────────────────────────── const ventas = [ { vendedor: "Ana", producto: "Laptop", monto: 1200, mes: "enero" }, { vendedor: "Carlos", producto: "Mouse", monto: 25, mes: "enero" }, { vendedor: "Ana", producto: "Monitor", monto: 450, mes: "febrero" }, { vendedor: "Bea", producto: "Teclado", monto: 75, mes: "enero" }, { vendedor: "Carlos", producto: "Laptop", monto: 1200, mes: "febrero" }, { vendedor: "Ana", producto: "Mouse", monto: 25, mes: "febrero" }, { vendedor: "Bea", producto: "Monitor", monto: 450, mes: "febrero" }, ]; // Funciones puras de análisis const filtrarPor = campo => valor => item => item[campo] === valor; const sumarCampo = campo => arr => arr.reduce((acc, i) => acc + i[campo], 0); const agruparPor = campo => arr => { const grupos = {}; for (const item of arr) { const clave = item[campo]; if (!grupos[clave]) grupos[clave] = []; grupos[clave].push(item); } return grupos; }; const totalGeneral = sumarCampo("monto")(ventas); const porVendedor = agruparPor("vendedor")(ventas); let html = `<strong class="ok">Total general: $${totalGeneral.toLocaleString()}</strong><br><br>`; html += `<table style="width:100%;border-collapse:collapse"> <tr> <th style="background:#F7DF1E;padding:6px 10px;text-align:left">Vendedor</th> <th style="background:#F7DF1E;padding:6px 10px;text-align:left">Ventas</th> <th style="background:#F7DF1E;padding:6px 10px;text-align:left">Total</th> </tr>`; for (const vendedor in porVendedor) { const grupo = porVendedor[vendedor]; const total = sumarCampo("monto")(grupo); const pct = Math.round(total / totalGeneral * 100); html += `<tr> <td style="padding:6px 10px;border-bottom:1px solid #eee">${vendedor}</td> <td style="padding:6px 10px;border-bottom:1px solid #eee">${grupo.length}</td> <td style="padding:6px 10px;border-bottom:1px solid #eee">$${total} (${pct}%)</td> </tr>`; } html += "</table>"; document.getElementById("reporte").innerHTML = html; </script> </body> </html>