Formas de declarar funciones en JavaScript: guía técnica y práctica
Declaración de función tradicional (function declaration)
Es la forma más clásica y se define utilizando la palabra clave function seguida de un nombre obligatorio. Una de sus características técnicas más distintivas es el hoisting (elevación), que permite invocar la función en líneas de código anteriores a su definición física dentro del archivo.
Ejemplo con parámetros:
function saludar(nombre) {
return `Hola, ${nombre}!`;
}
console.log(saludar("Mundo")); // "Hola, Mundo!"Expresión de función (function expression)
En este método, se trata a la función como un valor de datos que se asigna a una variable. Aquí puedes utilizar let, var o const para declarar dicha variable. A diferencia de las declaraciones, estas no están sujetas al hoisting completo; la función no existe hasta que el flujo de ejecución llega a la línea de asignación.
- Anónima: No tiene nombre propio.
- Nombrada: Incluye un identificador interno útil para recursión y depuración (aparece en el stack trace).
Ejemplo:
const sumar = function(a, b) {
return a + b;
}; // Se recomienda 'const' para evitar reasignaciones accidentalesFunciones de flecha (arrow functions)
Introducidas en ES6, ofrecen una sintaxis muy compacta y eliminan la necesidad de la palabra clave function. Su mayor diferencia semántica es que no tienen su propio enlace a this, sino que lo heredan del ámbito léxico que las rodea.
- Sintaxis corta: Si solo tienen un parámetro y una línea de código, se pueden omitir paréntesis, llaves y el
returnexplícito.
Ejemplo:
const cuadrado = x => x * x; // Retorno implícitoDefinición de métodos en objetos y clases (shorthand)
Es una sintaxis abreviada para declarar funciones dentro de objetos literales o clases, omitiendo los dos puntos y la palabra clave function. Estos métodos son los únicos que tienen acceso al enlace super.
Ejemplo en objeto:
const calculadora = {
valor: 10,
duplicar() {
return this.valor * 2;
} // Sintaxis limpia
};Funciones asíncronas (async)
Marcadas con el prefijo async, estas funciones siempre devuelven una promesa. Permiten el uso de await dentro de su cuerpo para pausar la ejecución de forma no bloqueante hasta que una promesa se resuelva.
Ejemplo:
async function obtenerDatos() {
const respuesta = await fetch('url');
return respuesta.json();
}Funciones generadoras (function*)
Se definen con function* y permiten una ejecución no continua; pueden pausar su estado y ceder el control al invocador mediante la palabra clave yield.
Ejemplo:
function* contador() {
yield 1;
yield 2;
}Expresiones de función ejecutadas inmediatamente (IIFE)
Son funciones que se ejecutan en cuanto se definen. Se utilizan principalmente para crear un ámbito privado y evitar contaminar el espacio de nombres global.
Ejemplo:
(function() {
const mensaje = "Privado";
console.log(mensaje);
})();Constructor Function (no recomendado)
Permite crear funciones dinámicamente a partir de cadenas de texto en tiempo de ejecución. No se recomienda su uso por riesgos de seguridad y falta de optimización por parte de los motores de JavaScript.
Ejemplo:
const sumarDinamico = new Function('a', 'b', 'return a + b');Analogía para entender las diferencias
Imagina que una declaración de función es como una receta grabada en piedra en la cocina: siempre ha estado ahí y todos saben dónde encontrarla incluso antes de empezar el turno. Una expresión de función es como una nota adhesiva que escribes en el momento: solo puedes seguir las instrucciones después de haberla escrito y pegado en la pared. Finalmente, una función de flecha es como un atajo mental que usa el contexto de lo que ya estás haciendo para completar una tarea rápida sin necesidad de una cocina entera.