Volver
Ctrl+Space
◑
Copiar
Descargar
Restaurar
Ejecutar
Ctrl+Enter
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Funciones en JS — Ejemplo 3</title> <style> body { font-family: Arial, sans-serif; padding: 20px; background: #fff; max-width: 650px; } 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; } </style> </head> <body> <h2>Funciones — Arrow functions, scope y closures</h2> <h3>Arrow functions — todas las formas</h3> <table id="tabla-arrow"></table> <h3>Arrow functions en métodos de array</h3> <div class="bloque"><div class="label">map / filter / sort</div><ul id="lista-array"></ul></div> <h3>Scope — qué variable es accesible dónde</h3> <div class="bloque"><div class="label">variables globales y locales</div><ul id="lista-scope"></ul></div> <h3>Closures — funciones que recuerdan su entorno</h3> <div class="bloque"><div class="label">crearContador()</div><ul id="lista-closure"></ul></div> <div class="bloque"><div class="label">crearAcumulador(inicio)</div><ul id="lista-acum"></ul></div> <script> // Funciones en JavaScript - Ejemplo 3: Arrow functions, scope y closures // ── Arrow functions ──────────────────────────────────────────────────── // Varias formas de escribir lo mismo const cuadradoA = function(n) { return n * n; }; // expresión clásica const cuadradoB = (n) => { return n * n; }; // arrow con {} const cuadradoC = n => n * n; // arrow corta const saludar = nombre => `Hola, ${nombre}!`; const sumar = (a, b) => a + b; const siempre42 = () => 42; const esPar = n => n % 2 === 0; const maximo = (a, b) => a > b ? a : b; const tablaA = document.getElementById("tabla-arrow"); tablaA.innerHTML = `<tr><th>Expresión</th><th>Resultado</th></tr>`; [ ["cuadradoA(7)", String(cuadradoA(7))], ["cuadradoB(7)", String(cuadradoB(7))], ["cuadradoC(7)", String(cuadradoC(7))], ["saludar('Ana')", saludar("Ana")], ["sumar(8, 5)", String(sumar(8, 5))], ["siempre42()", String(siempre42())], ["esPar(6)", String(esPar(6))], ["esPar(7)", String(esPar(7))], ["maximo(10, 35)", String(maximo(10, 35))], ].forEach(([expr, res]) => { tablaA.innerHTML += `<tr><td>${expr}</td><td>${res}</td></tr>`; }); // ── Arrow en métodos de array ────────────────────────────────────────── const productos = [ { nombre: "Laptop", precio: 1200, stock: 5 }, { nombre: "Mouse", precio: 25, stock: 0 }, { nombre: "Teclado", precio: 75, stock: 8 }, { nombre: "Monitor", precio: 450, stock: 2 }, ]; const disponibles = productos .filter(p => p.stock > 0) .sort((a, b) => a.precio - b.precio) .map(p => `${p.nombre} $${p.precio}`); const total = productos.reduce((acc, p) => acc + p.precio * p.stock, 0); const nombres = productos.map(p => p.nombre); const listaArr = document.getElementById("lista-array"); [ `Todos: [${nombres.join(", ")}]`, `Disponibles: [${disponibles.join(", ")}]`, `Total invent: $${total.toLocaleString()}`, ].forEach(txt => { const li = document.createElement("li"); li.textContent = txt; listaArr.appendChild(li); }); // ── Scope ────────────────────────────────────────────────────────────── const variableGlobal = "SOY GLOBAL"; function ejemploScope() { const variableLocal = "SOY LOCAL"; const resultados = [ `Dentro de la función — global: "${variableGlobal}"`, `Dentro de la función — local: "${variableLocal}"`, ]; return resultados; } const listaScope = document.getElementById("lista-scope"); ejemploScope().forEach(txt => { const li = document.createElement("li"); li.textContent = txt; listaScope.appendChild(li); }); // Intento de acceder a variable local desde afuera const li1 = document.createElement("li"); li1.textContent = `Fuera de la función — global: "${variableGlobal}"`; listaScope.appendChild(li1); try { const li2 = document.createElement("li"); // variableLocal no existe aquí — causaría ReferenceError li2.textContent = `Fuera — local: variable no accesible (correcto)`; li2.style.color = "#059669"; listaScope.appendChild(li2); } catch(e) { const li2 = document.createElement("li"); li2.textContent = `Error esperado: ${e.message}`; listaScope.appendChild(li2); } // ── Closures ─────────────────────────────────────────────────────────── function crearContador(inicio = 0) { let count = inicio; // esta variable "vive" en el closure return { incrementar: () => ++count, decrementar: () => --count, reset: () => { count = inicio; return count; }, valor: () => count, }; } const contA = crearContador(0); const contB = crearContador(10); // independiente de contA const listaClosure = document.getElementById("lista-closure"); [ `contA.incrementar() → ${contA.incrementar()}`, `contA.incrementar() → ${contA.incrementar()}`, `contA.incrementar() → ${contA.incrementar()}`, `contA.decrementar() → ${contA.decrementar()}`, `contA.valor() → ${contA.valor()}`, `contB.valor() → ${contB.valor()} (independiente)`, `contB.incrementar() → ${contB.incrementar()}`, `contA.reset() → ${contA.reset()} (solo afecta a contA)`, `contB.valor() → ${contB.valor()} (contB no cambió)`, ].forEach(txt => { const li = document.createElement("li"); li.textContent = txt; listaClosure.appendChild(li); }); // Closure como acumulador function crearAcumulador(inicio = 0) { let total = inicio; return monto => { total += monto; return total; }; } const caja = crearAcumulador(0); const listaAcum = document.getElementById("lista-acum"); [200, 350, 150, 500, 80].forEach(monto => { const nuevo = caja(monto); const li = document.createElement("li"); li.textContent = `+ $${monto} → total: $${nuevo}`; listaAcum.appendChild(li); }); </script> </body> </html>