HOWTO · JavaScript
Pasar la función de JavaScript como parámetro
Para pasar una función en JavaScript, proporciona su referencia —por ejemplo, `greet`— sin llamarla. Escribir `greet()` la ejecuta de inmediato y pasa su valor de retorno. La función receptora decide si llama a la función recibida y cuándo hacerlo; a menudo, esta función se denomina función de callback. Así puedes proporcionar un comportamiento para que otra función lo utilice.
En esta página
Para pasar una función en JavaScript, proporciona a la función receptora su referencia, como greet, sin invocarla. Al escribir greet() la ejecutas de inmediato y pasas su valor de retorno. La función receptora decide si llama a la función que recibe y cuándo hacerlo; esa función suele llamarse función de callback. Esta distinción permite proporcionar el comportamiento que otra función utilizará.
Pasar una función con nombre como argumento
Una función con nombre resulta útil cuando quieres describir una operación por separado o reutilizarla. En este ejemplo, formatGreeting recibe la función greet y un nombre. Luego llama a la función recibida con ese nombre:
function greet(name) {
return "Hello, " + name + "!";
}
function formatGreeting(callback, name) {
return callback(name);
}
const message = formatGreeting(greet, "Mina");
console.log(message);
La llamada formatGreeting(greet, "Mina") pasa dos valores: la referencia a una función greet y la cadena "Mina". Dentro de la función receptora, callback(name) invoca greet y devuelve su resultado. Si escribieras formatGreeting(greet("Mina"), "Mina"), JavaScript llamaría a greet antes de que comenzara formatGreeting, así que el primer argumento sería una cadena y no una función.
Pasar una función junto con otros argumentos
Una función puede recibir varios callbacks junto con valores normales. La función receptora puede elegir qué callback llamar y qué valor proporcionarle. Aquí, applyOperation recibe un número y dos funciones, y aplica cada función al número:
function applyOperation(value, first, second) {
return [first(value), second(value)];
}
function double(number) {
return number * 2;
}
function addThree(number) {
return number + 3;
}
const results = applyOperation(4, double, addThree);
console.log(results.join(", "));
El orden de los argumentos importa porque los parámetros de applyOperation reciben los valores en el mismo orden en que aparecen en la llamada. value recibe 4, first recibe double y second recibe addThree. La función devuelve ambos valores calculados dentro de un array. Este mismo patrón sirve cuando una API espera un callback junto con opciones o datos: comprueba el orden de sus parámetros y pasa cada función por su nombre, sin invocarla.
Usar funciones anónimas y de flecha como callbacks
Cuando solo necesitas una operación en el lugar donde haces la llamada, puedes definirla allí en vez de declarar una función con nombre. El siguiente ejemplo pasa una función anónima a map y luego pasa una función de flecha a una segunda llamada a map:
const numbers = [1, 2, 3];
const doubled = numbers.map(function (number) {
return number * 2;
});
const tripled = numbers.map((number) => number * 3);
console.log(doubled.join(", "));
console.log(tripled.join(", "));
2, 4, 6
3, 6, 9
map invoca su callback para cada elemento del array y crea un array nuevo con los valores devueltos; no es necesario que el callback tenga nombre. La función anónima utiliza la palabra clave function, mientras que la función de flecha utiliza => y un cuerpo de expresión cuyo valor se devuelve de forma implícita. Elige la forma que permita entender mejor la operación. Las funciones de flecha también usan el this léxico del contexto circundante; si el callback necesita su propio valor de this, usa una función normal y consulta el comportamiento de this documentado por la API que la invoca.
Devolver una función desde otra función
Una función también puede devolver otra función. Esto es distinto de pasar un callback como argumento: la llamada externa crea y devuelve una función que puedes guardar e invocar más tarde. Por ejemplo, makeMultiplier devuelve una función que conserva el multiplicador elegido en su ámbito circundante:
function makeMultiplier(multiplier) {
return function (number) {
return number * multiplier;
};
}
const triple = makeMultiplier(3);
console.log(triple(5));
makeMultiplier(3) devuelve una función, así que triple hace referencia a esa función devuelta. Al llamar a triple(5), proporcionas su argumento number. La función interna aún puede leer multiplier de la llamada que la creó; este acceso conservado se denomina cierre. Una función de orden superior es una función que acepta otra función, devuelve una o hace ambas cosas.
Preguntas frecuentes
¿Cómo paso varias funciones? Coloca cada referencia a una función en su propia posición de argumento, separadas por comas, y respeta el orden de los parámetros de la función receptora.
¿Cuándo se ejecuta un callback? La función receptora determina cuándo lo invoca. Pasar una función no la ejecuta; según su diseño, la función receptora puede llamarla de inmediato, más tarde o más de una vez.
¿Puede una función devolver otra función? Sí. Llama a la función externa para obtener la función devuelta y luego llama a ese resultado o pásalo según lo necesites. Esto se usa a menudo para crear funciones con una configuración capturada en un cierre.