Funciones Flecha y Callbacks en JavaScript

Funciones Flecha y Callbacks en JavaScript

(Para alumnos de secundaria - ¡Sin miedo al código!)


📚 ¿Qué vamos a aprender?

  1. Qué son las funciones flecha (y por qué tienen forma de =>)

  2. Qué son los callbacks (funciones que llaman a otras funciones)

  3. Por qué se usan para "no perder el contexto" (el famoso this)


🧠 Analogía 1: La receta de cocina

Imagina que tienes una receta (función principal) que dice:
"Hierve agua, luego CUANDO esté hirviendo (callback), agrega la pasta"

El callback es esa acción de "agregar pasta" que se ejecuta después de un evento.


🏹 Funciones Flecha: La versión "atajo"

Función normal (larga):

javascript
function saludar(nombre) {
  return "Hola " + nombre;
}

Función flecha (corta):

javascript
const saludar = (nombre) => "Hola " + nombre;

¿Ves la flecha =>? Significa: "esto devuelve aquello"

Ejemplo con más pasos:

javascript
// Normal
function sumar(a, b) {
  return a + b;
}

// Flecha
const sumar = (a, b) => a + b;

console.log(sumar(3, 4)); // 7

Regla mnemotécnica: La flecha => apunta hacia el resultado.


🔄 Callbacks: Cuando una función llama a otra

Imagina que eres director de una escuela. Tienes una función hacerTarea() que recibe qué hacer como parámetro.

Ejemplo simple:

javascript
function hacerTarea(tarea, callback) {
  console.log("Haciendo: " + tarea);
  callback(); // ¡Aquí llamamos al callback!
}

function avisarTermine() {
  console.log("✅ ¡Tarea completada!");
}

hacerTarea("Matemáticas", avisarTermine);
// Imprime:
// Haciendo: Matemáticas
// ✅ ¡Tarea completada!

🎮 Analogía 2: El botón de un videojuego

En un juego, presionar espacio (evento) ejecuta saltar (callback).
No sabes cuándo pasará, pero cuando ocurra, ¡el callback reacciona!

javascript
// Simulamos un botón
function cuandoPresionenEspacio(callback) {
  // Esto sería un evento real en el navegador
  console.log("Esperando que presiones espacio...");
  // Supón que aquí el usuario presiona espacio
  callback(); // Entonces ejecuta lo que le pedimos
}

cuandoPresionenEspacio(() => {
  console.log("¡EL PERSONAJE SALTÓ! 🦘");
});

🔍 El problema del contexto (el this perdido)

¿Qué es this en una función normal?

En JavaScript, this es como un pronombre ("yo", "tú", "él") que cambia según quién habla.

javascript
const alumno = {
  nombre: "Carlos",
  saludarNormal: function() {
    console.log("Hola, soy " + this.nombre);
  }
};

alumno.saludarNormal(); // "Hola, soy Carlos" ✅

PERO si guardamos la función en una variable:

javascript
const saludoSuerto = alumno.saludarNormal;
saludoSuerto(); // "Hola, soy undefined" ❌ (perdió el "contexto")

Porque this ahora es el objeto global (como la ventana del navegador).


🛡️ Las funciones flecha NO cambian el this

Las funciones flecha no crean su propio this. Usan el this del lugar donde nacieron.

Analogía 3: La pulsera de identificación

Imagina que entras a un parque de diversiones con una pulsera (tu contexto).
Una función normal es como comprar un nuevo boleto en cada juego: pierdes la pulsera original.
Una función flecha es como mantener siempre la misma pulsera: saben quién eres.

javascript
const alumno = {
  nombre: "María",
  
  // ❌ Con función normal (pierde el contexto)
  mostrarNormal: function() {
    function quienSoy() {
      console.log(this.nombre); // ❌ undefined
    }
    quienSoy();
  },
  
  // ✅ Con función flecha (mantiene el contexto)
  mostrarFlecha: function() {
    const quienSoy = () => {
      console.log(this.nombre); // ✅ "María"
    }
    quienSoy();
  }
};

alumno.mostrarFlecha(); // María

🎯 Explicación:

  • Función normalthis cambia y se pierde

  • Función flechathis sigue siendo alumno

Regla: Si necesitas usar this dentro de otra función, usa arrow function (=>)


📱 Ejemplo del mundo real: Temporizador

javascript
const miApp = {
  mensaje: "Cargando...",
  
  iniciar: function() {
    // Con función normal (mal)
    setTimeout(function() {
      console.log(this.mensaje); // undefined ❌
    }, 1000);
    
    // Con función flecha (bien)
    setTimeout(() => {
      console.log(this.mensaje); // "Cargando..." ✅
    }, 2000);
  }
};

miApp.iniciar();

✅ Resumen visual

CaracterísticaFunción NormalFunción Flecha
Sintaxisfunction() {}() => {}
Su propio thisSí (cambia)No (lo hereda)
Útil para callbacks❌ Riesgo de perder contexto✅ Perfecta
Se puede usar como métodoDepende (mejor normal para métodos)

🎯 Ejercicio para practicar

javascript
// 1. Crea un objeto "estudiante" con nombre y un array de hobbies
// 2. Agrega un método "mostrarHobbies" que use forEach con función flecha
// 3. Debe imprimir "Juan disfruta el fútbol", etc.

const estudiante = {
  nombre: "Lucía",
  hobbies: ["dibujar", "programar", "jugar basket"],
  mostrarHobbies: function() {
    this.hobbies.forEach((hobby) => {
      console.log(`${this.nombre} disfruta ${hobby}`);
    });
  }
};

estudiante.mostrarHobbies();
// Lucía disfruta dibujar
// Lucía disfruta programar
// Lucía disfruta jugar basket

💡 Conclusión para recordar

  1. Las funciones flecha (=>) son atajos para escribir funciones cortas.

  2. Los callbacks son funciones que se pasan como parámetro para ejecutarse después.

  3. No perder el contexto significa que this no cambia, ¡como una pulsera que nunca te quitas!

  4. Usa flechas EN callbacks cuando necesites acceder al this del objeto padre.


🧪 Prueba mental

Si ves este código:

javascript
button.addEventListener("click", () => {
  console.log(this.texto);
});

El this dentro de la flecha NO es el botón, sino el this que existía fuera (el objeto padre). Eso es contexto preservado ✅.

¡Ya estás listo para usar funciones flecha como un profesional! 


Funciones flecha (=>

Es una forma más corta de escribir funciones.

javascript

// Función normal

function saludar(nombre) {

  return "Hola " + nombre;

}


// Función flecha

const saludar = (nombre) => "Hola " + nombre;

console.log(saludar("Juan")); // "Hola Juan"

Regla simple:
(parámetros) => resultado

  • Si hay un solo parámetro, puedes omitir el paréntesis: nombre => ...

  • Si es una sola línea, el return es implícito (no hace falta escribirlo)

Funciones callback

Es una función que se pasa como argumento a otra función, para que esta la ejecute después.

javascript

// Ejemplo muy simple

function hacerAlgo(callback) {

  console.log("Haciendo algo...");

  callback(); // Aquí ejecutamos la función que nos pasaron

}

// Usamos la función pasando un callback

hacerAlgo(function() {

  console.log("¡Callback ejecutado!");

});


// Con flecha (más común y limpio)

hacerAlgo(() => console.log("¡Callback ejecutado!"));

Ejemplo real y útil

javascript

// Array de números

const numeros = [1, 2, 3, 4, 5];

// map recibe un callback para transformar cada elemento

const dobles = numeros.map(numero => numero * 2);

console.log(dobles); // [2, 4, 6, 8, 10]

Explicación:

  • map recorre el array

  • Para cada número, ejecuta numero => numero * 2

  • Ese callback es una función flecha que multiplica por 2

Resumen visual

javascript

// Función normal como callback

setTimeout(function() {

  console.log("Pasó 1 segundo");

}, 1000);

// Función flecha como callback (más común hoy)

setTimeout(() => console.log("Pasó 1 segundo"), 1000);

Idea clave: La función flecha es la sintaxis moderna y suele usarse mucho como callback porque es más corta y legible.


¡Perfecto! Las funciones callback son la pieza que une todo. Te explico desde cero:

1. ¿Qué es un Callback?

Callback = Una función que pasas a otra función para que ELLA la ejecute después

javascript

// Tú creas esta función

function saludar() {

    console.log("Hola");

}


// La pasas a otra función (setTimeout)

setTimeout(saludar, 1000);

//        ↑

//     Este es el CALLBACK


// setTimeout recibe saludar y la ejecuta después de 1 segundo

2. Ejemplo básico de Callback

javascript

// Función que recibe un callback

function hacerTarea(nombre, callback) {

    console.log(`Haciendo: ${nombre}`);

    

    // Después de hacer la tarea, ejecuto el callback

    callback();  // ← Aquí ejecuto la función que me pasaron

}


// Usar la función con un callback

function cuandoTermine() {

    console.log("¡Tarea completada!");

}


hacerTarea("Limpiar", cuandoTermine);

// Salida:

// Haciendo: Limpiar

// ¡Tarea completada!

3. Callback con parámetros

javascript

function procesarUsuario(nombre, callback) {

    console.log(`Procesando a ${nombre}...`);

    

    // Simular trabajo

    const resultado = `Usuario ${nombre} procesado`;

    

    // Ejecutar callback pasándole el resultado

    callback(resultado);

}


// Usar

procesarUsuario("Juan", (mensaje) => {

    console.log("Callback recibió:", mensaje);

});


// Salida:

// Procesando a Juan...

// Callback recibió: Usuario Juan procesado

4. Callback en addEventListener (el que ya conoces)

javascript

// Tú creas el callback

function cuandoHaganClick() {

    console.log("¡Alguien hizo click!");

}


// Se lo pasas al navegador

boton.addEventListener("click", cuandoHaganClick);

//                                 ↑

//                              Callback


// El navegador GUARDA tu callback y lo EJECUTA cuando hay click


5. Callback en setTimeout

javascript

// Callback como función normal

function despertar() {

    console.log("¡Es hora de despertar!");

}


setTimeout(despertar, 3000);  // Ejecuta después de 3 segundos


// Callback como función flecha (más común)

setTimeout(() => {

    console.log("Pasaron 2 segundos");

}, 2000);

6. ¡AHORA SÍ! Callback en EXPRESS

Express funciona EXACTAMENTE igual que addEventListener y setTimeout:

javascript

// === addEventListener ===

boton.addEventListener("click", (evento) => {

    console.log("Click en botón");

});

// El navegador ejecuta el callback cuando hay click


// === setTimeout ===

setTimeout(() => {

    console.log("Tiempo cumplido");

}, 1000);

// JavaScript ejecuta el callback después de 1 segundo


// === EXPRESS ===

app.get('/', (req, res) => {

    res.send("Página principal");

});

// Express ejecuta el callback cuando alguien visita '/'

7. Express por dentro (simplificado)

javascript

// Así funciona Express internamente

class Express {

    constructor() {

        this.rutas = {};  // Donde guarda los callbacks

    }

    

    // Método get (como addEventListener)

    get(url, callback) {

        console.log(`📦 Guardando callback para ${url}`);

        this.rutas[url] = callback;  // Guarda el callback

    }

    

    // Cuando llega una petición

    recibirPeticion(url) {

        console.log(`🌐 Llegó petición a ${url}`);

        

        // Buscar el callback guardado

        const callback = this.rutas[url];

        

        if (callback) {

            console.log(`✅ Ejecutando callback...`);

            

            // Crear req y res simulados

            const req = { url: url };

            const res = {

                send: (mensaje) => console.log(`   Enviando: ${mensaje}`)

            };

            

            // ¡EJECUTA EL CALLBACK!

            callback(req, res);

        }

    }

}


// ===== USO (igual que Express real) =====

const app = new Express();


// Tú guardas el callback

app.get('/', (req, res) => {

    res.send("Hola Mundo");

});


app.get('/about', (req, res) => {

    res.send("Acerca de");

});


// Tiempo después, llegan peticiones

console.log("\n=== SIMULANDO PETICIONES ===\n");

app.recibirPeticion('/');

app.recibirPeticion('/about');

app.recibirPeticion('/contacto');

Salida:

text

📦 Guardando callback para /

📦 Guardando callback para /about


=== SIMULANDO PETICIONES ===


🌐 Llegó petición a /

✅ Ejecutando callback...

   Enviando: Hola Mundo


🌐 Llegó petición a /about

✅ Ejecutando callback...

   Enviando: Acerca de


🌐 Llegó petición a /contacto

8. El patrón completo que une todo

javascript

// MISMO PATRÓN en diferentes situaciones:


// 1. Botón (callback ejecutado por navegador)

boton.addEventListener("click", (e) => {

    console.log("Click");

});


// 2. Temporizador (callback ejecutado por JavaScript)

setTimeout(() => {

    console.log("Tiempo");

}, 1000);


// 3. Express (callback ejecutado por servidor)

app.get('/ruta', (req, res) => {

    console.log("Petición recibida");

});


// 4. Tu propia función (callback ejecutado por ti)

function hacerAlgo(callback) {

    console.log("Haciendo algo...");

    callback();  // Tú ejecutas el callback

}


hacerAlgo(() => {

    console.log("Callback ejecutado");

});

9. Por qué NO poner () en Express (ya con callback claro)

javascript

// TÚ: Pasas el callback (sin ejecutar)

app.get('/', (req, res) => {

    res.send("Hola");

});

//        ↑

//     Callback guardado, NO ejecutado


// EXPRESS: Recibe el callback y lo guarda

// Cuando llegue la petición, Express EJECUTA:

// callback(req, res)


// ❌ INCORRECTO (ejecutas el callback TÚ mismo)

app.get('/', (req, res) => {

    res.send("Hola");

}());  // ¡Los () ejecutan AHORA!

// El resultado (undefined) es lo que recibe Express


// ES COMO HACER:

const resultado = (req, res) => { res.send("Hola"); }();

app.get('/', resultado);  // resultado es undefined, no una función

10. Ejemplo visual de Callback en Express

javascript

// Tu controller (objeto con funciones callback)

const productoController = {

    // Esto es un CALLBACK (función que pasas a Express)

    mostrarIndex: (req, res) => {

        res.render('index');

    }

};


// Le PASAS el callback a Express (sin ejecutar)

app.get('/', productoController.mostrarIndex);

//                         ↑

//                      Callback


// Express INTERNAMENTE hace:

const callbackGuardado = productoController.mostrarIndex;


// Cuando alguien visita /:

// Express EJECUTA: callbackGuardado(req, res)

Resumen final (lo que necesitas recordar)

javascript

// CALLBACK = Función que pasas para que OTRA la ejecute DESPUÉS


// 1. Tú CREAS la función (callback)

function miCallback() {

    console.log("Ejecutado");

}


// 2. Tú la PASAS (sin ejecutar)

algo.esperarEvento(miCallback);  // Sin ()


// 3. ELLOS la EJECUTAN cuando corresponde

// (navegador, setTimeout, Express, etc.)


// En Express ES IGUAL:

app.get('/', (req, res) => {  // ← Este es un callback

    res.send("Respuesta");

});

// Express guarda este callback y lo ejecuta cuando visitan la ruta

La conexión final: Express, addEventListener, y setTimeout son la misma cosa: reciben un callback (tu función) y la ejecutan cuando ocurre el evento (click, tiempo cumplido, petición HTTP). ¡Por eso todos usan la misma regla de NO poner () cuando los pasas!


Comentarios

Entradas más populares de este blog

1-valores duplicados en un arreglo

n-funcion - el botón-n

Objetos básicos en JavaScript