Menu

Funciones en JavaScript: declaración, hoisting y return

Cómo declarar funciones en JavaScript: la palabra clave function, parámetros, valores de retorno, hoisting y cuándo usar una declaración en lugar de una expresión.

Una función es un bloque de pasos con nombre

Siempre que quieras ponerle nombre a un trozo de lógica para reutilizarlo, lo que escribes es una función. La forma más antigua y directa de hacerlo en JavaScript es la declaración de función: la palabra clave function seguida de un nombre.

index.js
Output
Click Run to see the output here.

Leyendo eso de principio a fin:

  • function es la palabra clave con la que empieza una declaración de función.
  • greet es el nombre de la función.
  • (name) es la lista de parámetros: las entradas que recibe la función.
  • El bloque entre llaves es el cuerpo.
  • greet("Ada") es una llamada. JavaScript ejecuta el cuerpo con name ligado a "Ada".

Definir una función no la ejecuta. Llamarla, sí.

Parámetros y argumentos

La palabra parámetro se refiere al nombre que aparece dentro de la definición de la función. El argumento, en cambio, es el valor que pasas al hacer la llamada. En el día a día se usan como sinónimos, pero la diferencia importa cuando te toca leer mensajes de error.

index.js
Output
Click Run to see the output here.

Aquí base y exponent son parámetros. 2 y 10 son argumentos. JavaScript los enlaza en orden: el primer argumento al primer parámetro, y así sucesivamente.

A diferencia de otros lenguajes, JavaScript no se queja si le pasas una cantidad distinta de argumentos. Los que falten quedan como undefined y los que sobran simplemente se ignoran. Esa flexibilidad es útil, pero también puede jugarte una mala pasada; más adelante veremos los valores por defecto y los parámetros rest.

return: devolver un valor desde la función

console.log escribe en la salida. return, en cambio, entrega un valor a quien llamó a la función para que pueda usarlo:

index.js
Output
Click Run to see the output here.

Sin return, la función devuelve undefined:

index.js
Output
Click Run to see the output here.

return también sale de la función de inmediato. Los early returns son la forma habitual de descartar casos límite antes de llegar a la lógica principal:

index.js
Output
Click Run to see the output here.

Los return tempranos evitan que el cuerpo principal se convierta en una pirámide de if/else.

Hoisting en funciones de JavaScript: llamarlas antes de declararlas

Aquí viene algo que deja descolocada a mucha gente que llega desde otros lenguajes. Las declaraciones de función sufren hoisting: JavaScript las sube al principio de su ámbito antes de ejecutar cualquier código. En la práctica, esto significa que puedes invocar una función varias líneas antes de donde la declaras:

index.js
Output
Click Run to see the output here.

Ese código funciona sin problema. Antes de ejecutar, el motor recorre el ámbito, registra square como función y recién entonces empieza a ejecutar las sentencias de arriba hacia abajo.

Esta es una diferencia real de comportamiento entre las declaraciones de función y las otras formas de crear una función (expresiones de función y funciones flecha). Estas últimas se elevan como variables: el nombre se conoce, pero el valor no se asigna hasta que la línea se ejecuta. Ya veremos esa diferencia con más detalle.

De todos modos, la mayoría de las guías de estilo recomiendan definir las funciones antes de llamarlas. El hoisting es una red de seguridad, no un estilo en el que apoyarse.

Declaración vs expresión de función

Una declaración de función se sostiene por sí sola como una sentencia. Una expresión de función aparece donde se espera un valor, lo más habitual al asignarla a una variable:

index.js
Output
Click Run to see the output here.

Ambas producen funciones invocables. Las diferencias son estas:

  • Las declaraciones se elevan (hoisting) por completo. Las expresiones siguen las reglas de hoisting de la variable a la que se asignan (con const y let quedan en la zona muerta temporal hasta que se ejecuta la línea).
  • Las declaraciones tienen que llevar nombre. Las expresiones pueden ser anónimas, aunque ponerles nombre ayuda en los stack traces.
  • Las declaraciones no se pueden colocar en cualquier lado. En modo estricto, un function foo() {} dentro de un bloque if se comporta de forma distinta según el motor; ahí lo mejor es usar una expresión.

Para la mayoría de funciones auxiliares en el nivel superior de un archivo, una declaración se lee muy bien. Para funciones que pasas como argumento o que asignas a propiedades, lo habitual es una expresión (o una arrow function).

Nombres y estilo

El nombre de una función es una promesa de lo que esa función hace. Dedicarle unos caracteres de más para elegir uno descriptivo se paga solo la primera vez que alguien vuelve a leer el código.

index.js
Output
Click Run to see the output here.

Algunas convenciones que conviene adoptar:

  • Los nombres de funciones deberían ser verbos: fetchProfile, computeTotal, sendEmail.
  • Usa camelCase: es la norma en JavaScript.
  • Las funciones que devuelven un booleano suelen empezar con is, has o can: isValid, hasAccess, canEdit.

La idea es que, al invocar la función, la línea se lea casi como una frase.

Un ejemplo práctico y breve

Vamos a juntar todas las piezas: parámetros, un return temprano y un nombre descriptivo.

index.js
Output
Click Run to see the output here.

Una declaración, una cláusula de guarda y un return claro. Esa estructura te sirve para la mayoría de funciones que vas a escribir.

Siguiente: funciones flecha

Las declaraciones de función son la herramienta de siempre, pero el JavaScript moderno tira mucho de una sintaxis más corta —las funciones flecha—, sobre todo para callbacks y funciones de una sola línea. Se escriben distinto, se comportan distinto con this y de eso va precisamente la siguiente página.

Preguntas frecuentes

¿Cómo se declara una función en JavaScript?

Se usa la palabra clave function, seguida del nombre, los paréntesis con los parámetros y un bloque con el cuerpo. Por ejemplo: function saludar(nombre) { return 'Hola, ' + nombre; }. Para llamarla, basta con escribir su nombre seguido de paréntesis: saludar('Ada').

¿Qué es el hoisting de funciones en JavaScript?

Las declaraciones de función se "elevan" al inicio de su ámbito antes de ejecutarse el código, así que puedes invocarlas incluso en líneas anteriores a donde están escritas. Ojo: esto solo pasa con function. Las expresiones de función y las arrow functions asignadas a let o const no se comportan igual.

¿Cuál es la diferencia entre declaración y expresión de función?

Una declaración es una sentencia independiente (function saludar() {}) y sufre hoisting completo. Una expresión asigna la función a una variable (const saludar = function() {}) y se rige por las reglas normales de hoisting de variables. Además, las declaraciones siempre llevan nombre, mientras que las expresiones suelen ser anónimas.

Aprende a programar con Coddy

COMENZAR