Ir al contenido principal

Parámetros y argumentos

Introducción

Una de las características más poderosas de las funciones en JavaScript es su capacidad para recibir información externa y trabajar con ella. Para hacer esto posible, utilizamos los parámetros y argumentos. Estos elementos son fundamentales para crear código flexible y reutilizable, ya que permiten que una misma función trabaje con diferentes valores según lo necesitemos. En este artículo, aprenderemos a definir parámetros en nuestras funciones, cómo pasar argumentos y las diversas técnicas que JavaScript ofrece para manejarlos eficientemente.

Diferencia entre parámetros y argumentos

Aunque a menudo se usan indistintamente, los parámetros y los argumentos son conceptos diferentes:

  • Parámetros: Son las variables que se definen en la declaración de una función. Actúan como placeholders (espacios reservados) para los valores que recibirá la función.
  • Argumentos: Son los valores reales que pasamos a la función cuando la invocamos.

Veamos un ejemplo sencillo:

// Declaración de la función con dos parámetros: nombre y edad
function saludar(nombre, edad) {
  console.log(`¡Hola ${nombre}! Tienes ${edad} años.`);
}

// Invocación de la función con dos argumentos: "Ana" y 25
saludar("Ana", 25);

En este ejemplo, nombre y edad son los parámetros, mientras que "Ana" y 25 son los argumentos.

Definición de parámetros en funciones

Los parámetros se definen dentro de los paréntesis al declarar una función. Podemos definir tantos parámetros como necesitemos, separándolos por comas:

// Función sin parámetros
function saludarGenerico() {
  console.log("¡Hola a todos!");
}

// Función con un parámetro
function saludarPersona(nombre) {
  console.log(`¡Hola ${nombre}!`);
}

// Función con múltiples parámetros
function presentarPersona(nombre, edad, profesion) {
  console.log(`Te presento a ${nombre}, tiene ${edad} años y es ${profesion}.`);
}

Paso de argumentos al invocar

Al llamar a una función, pasamos los argumentos en el mismo orden en que se definieron los parámetros:

saludarGenerico(); // No requiere argumentos
saludarPersona("Carlos"); // Un argumento
presentarPersona("Laura", 28, "ingeniera"); // Tres argumentos

Comportamiento ante argumentos no inicializados

Si llamamos a una función con menos argumentos de los que espera, los parámetros sin argumento correspondiente recibirán el valor undefined:

function mostrarDatos(nombre, apellido, edad) {
  console.log(`Nombre: ${nombre}`);
  console.log(`Apellido: ${apellido}`);
  console.log(`Edad: ${edad}`);
}

mostrarDatos("Elena", "García"); 
// Muestra:
// Nombre: Elena
// Apellido: García
// Edad: undefined

Comportamiento ante el exceso de argumentos

Si pasamos más argumentos de los definidos como parámetros, los argumentos adicionales se ignoran (pero están disponibles a través del objeto arguments que veremos más adelante):

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

let resultado = sumar(5, 3, 10, 20); // Los valores 10 y 20 se ignoran
console.log(resultado); // 8

Parámetros por defecto

JavaScript moderno (ES6+) permite asignar valores por defecto a los parámetros. Estos valores se utilizan cuando no se proporciona un argumento o cuando el valor es undefined:

function saludar(nombre = "amigo", momento = "día") {
  console.log(`¡Buen ${momento}, ${nombre}!`);
}

saludar(); // ¡Buen día, amigo!
saludar("María"); // ¡Buen día, María!
saludar("Carlos", "tarde"); // ¡Buen tarde, Carlos!

Los valores por defecto pueden ser cualquier expresión, incluyendo llamadas a funciones:

function obtenerSaludo() {
  return "¡Saludos cordiales!";
}

function mensaje(texto = obtenerSaludo()) {
  console.log(texto);
}

mensaje(); // ¡Saludos cordiales!
mensaje("Hola a todos"); // Hola a todos

Parámetro rest (...)

El parámetro rest permite representar un número indefinido de argumentos como un array. Se denota con tres puntos (...) seguidos de un nombre:

function sumarTodos(...numeros) {
  let total = 0;
  for (let numero of numeros) {
    total += numero;
  }
  return total;
}

console.log(sumarTodos(1, 2, 3)); // 6
console.log(sumarTodos(5, 10, 15, 20)); // 50

El parámetro rest debe ser el último parámetro en la lista, ya que recoge "el resto" de los argumentos:

function crearEquipo(lider, segundo, ...miembros) {
  console.log(`Líder: ${lider}`);
  console.log(`Segundo al mando: ${segundo}`);
  console.log(`Otros miembros: ${miembros.join(", ")}`);
}

crearEquipo("Ana", "Luis", "Carlos", "Elena", "Jorge");
// Muestra:
// Líder: Ana
// Segundo al mando: Luis
// Otros miembros: Carlos, Elena, Jorge

Desestructuración en parámetros

La desestructuración permite extraer datos de arrays u objetos de forma más conveniente al recibir parámetros:

Desestructuración de arrays

function mostrarCoordenadas([x, y]) {
  console.log(`Posición X: ${x}`);
  console.log(`Posición Y: ${y}`);
}

const punto = [10, 20];
mostrarCoordenadas(punto);
// Muestra:
// Posición X: 10
// Posición Y: 20

Desestructuración de objetos

function mostrarUsuario({nombre, edad, ciudad = "Desconocida"}) {
  console.log(`Nombre: ${nombre}`);
  console.log(`Edad: ${edad}`);
  console.log(`Ciudad: ${ciudad}`);
}

const usuario = {
  nombre: "Roberto",
  edad: 32
};

mostrarUsuario(usuario);
// Muestra:
// Nombre: Roberto
// Edad: 32
// Ciudad: Desconocida

La desestructuración resulta especialmente útil cuando trabajamos con funciones que reciben objetos con muchas propiedades, ya que nos permite extraer sólo las que necesitamos.

El objeto arguments

Todas las funciones tradicionales en JavaScript (excepto las funciones flecha) tienen acceso a un objeto especial llamado arguments. Este objeto contiene todos los argumentos pasados a la función, independientemente del número de parámetros definidos:

function mostrarArgumentos() {
  console.log(arguments);
  console.log(`Total de argumentos: ${arguments.length}`);
  console.log(`Primer argumento: ${arguments[0]}`);
}

mostrarArgumentos("uno", "dos", "tres");
// Muestra:
// [Arguments] { '0': 'uno', '1': 'dos', '2': 'tres' }
// Total de argumentos: 3
// Primer argumento: uno

El objeto arguments no es un array real, aunque se parece a uno. Si necesitamos usar métodos de array, podemos convertirlo:

function sumar() {
  // Convertir arguments a array
  const numeros = Array.from(arguments);
  
  // Ahora podemos usar métodos de array como reduce
  return numeros.reduce((total, num) => total + num, 0);
}

console.log(sumar(1, 2, 3, 4)); // 10

Sin embargo, en JavaScript moderno es preferible usar el parámetro rest (...) en lugar de arguments.

Validación de parámetros

Es una buena práctica validar los parámetros recibidos para asegurar que tienen el tipo y formato esperados:

function dividir(dividendo, divisor) {
  // Validar que los parámetros sean números
  if (typeof dividendo !== "number" || typeof divisor !== "number") {
    throw new Error("Ambos parámetros deben ser números");
  }
  
  // Validar que el divisor no sea cero
  if (divisor === 0) {
    throw new Error("No se puede dividir por cero");
  }
  
  return dividendo / divisor;
}

try {
  console.log(dividir(10, 2)); // 5
  console.log(dividir("10", 2)); // Error: Ambos parámetros deben ser números
  console.log(dividir(10, 0)); // Error: No se puede dividir por cero
} catch (error) {
  console.error(error.message);
}

Buenas prácticas

  1. Nombres descriptivos: Usa nombres claros para tus parámetros que indiquen su propósito.
// Mal ejemplo
function calcular(a, b, c) { /* ... */ }

// Buen ejemplo
function calcularPrecioFinal(precioBase, tasaImpuesto, descuento) { /* ... */ }
  1. Número limitado de parámetros: Intenta mantener un número razonable de parámetros (idealmente no más de 3). Si necesitas pasar muchos valores, considera usar un objeto.
// Muchos parámetros (difícil de recordar el orden)
function crearUsuario(nombre, apellido, edad, email, telefono, direccion) { /* ... */ }

// Mejor con un objeto (más claro y flexible)
function crearUsuario({nombre, apellido, edad, email, telefono, direccion}) { /* ... */ }
  1. Valores por defecto sensatos: Proporciona valores por defecto que sean lógicos y reduzcan la necesidad de comprobaciones adicionales.

  2. Documenta tus parámetros: Especialmente en funciones complejas, documenta qué parámetros espera la función y de qué tipo deberían ser.

/**
 * Calcula el pago mensual de un préstamo.
 * @param {number} principal - Cantidad del préstamo
 * @param {number} tasaInteres - Tasa de interés anual (en decimales)
 * @param {number} plazoAnios - Plazo del préstamo en años
 * @return {number} El pago mensual
 */
function calcularPagoMensual(principal, tasaInteres, plazoAnios) {
  // implementación...
}

Resumen

Los parámetros y argumentos son elementos fundamentales en JavaScript que permiten crear funciones flexibles y reutilizables. Hemos aprendido a definir parámetros en funciones, cómo pasar argumentos al invocarlas, y técnicas avanzadas como parámetros por defecto, parámetro rest y desestructuración. También hemos visto la importancia de validar los parámetros recibidos para garantizar el correcto funcionamiento de nuestras funciones.

Dominar estos conceptos te permitirá crear código más modular, adaptable y robusto. En el próximo artículo, profundizaremos en la sentencia return y cómo trabajar con los valores devueltos por las funciones, completando así nuestro conocimiento sobre el funcionamiento básico de las funciones en JavaScript.