Inicio Funciones en JavaScript
Artículo
Cancelar

Funciones en JavaScript

Introducción

Las funciones son bloques fundamentales de código en JavaScript. Permiten agrupar y reutilizar código, y son esenciales para la programación modular, estructurada y funcional.

Lee el artículo ¿Qué es una función?.

¿Es lo mismo un parámetro que un argumento?

Casi pero no. Los parámetros son variables definidas en la declaración de una función y los argumentos son los valores reales que se pasan a la función cuando se invoca.

¿Qué es una función?

Las funciones nos permiten agrupar líneas de código en tareas con un nombre, para que, posteriormente, podamos hacer referencia a ese nombre para realizar todo lo que se agrupe en dicha tarea.

¿Es lo mismo declarar una función que ejecutar una función?

No.

¿Qué es un parámetro/argumentos?

¿Puede tener una función múltiples parámetros? ¿Cuál es el límite?

¿Existen los parámetros por defecto?

¿En qué consiste la devolución o retorno de valores? ¿Todas las funciones devuelven algo?

Variables Globales y Efectos Secundarios

Las funciones pueden utilizar y modificar variables globales, lo que puede llevar a efectos secundarios (side-effects).

1
2
3
4
5
6
let contador = 0;
function incrementar() {
  contador++;
}
incrementar();
console.log(contador); // 1

Salida:

1
1

En términos generales, evitaremos funciones que usen o modifiquen variables globales. Estas funciones son consideradas como no puras y veremos en posteriores capítulos porqué no se deben utilizar.

Parámetros de una función

Una característica notable de JavaScript es que no da error si llamas a una función con más argumentos de los que espera. Los argumentos adicionales simplemente son ignorados.

1
2
3
4
function saludar(nombre) {
  console.log("Hola, " + nombre);
}
saludar("Juan", "extra"); // "Hola, Juan"
1
Hola, Juan

El orden de los argumentos es crucial. Los argumentos se asignan a los parámetros en el orden en que se pasan.

Javascript, en las funciones, crea un objeto llamando arguments que tiene los argumentos pasados, la posición como clave y la cantidad de argumentos con length.

1
2
function a(){ console.log(arguments)} 
a(1,2,3);
1
[Arguments] { "0": 1, "1": 2, "2": 3 }

Lee el artículo Parámetros de una función.

¿Cuántas maneras existen de declarar una función? ¿Hay alguna no recomendada?

¿Cómo ejecutamos una función que no tiene nombre?

¿Qué es una función anónima?

Return en funciones

Las funciones pueden o no tener un valor de retorno. Si no se especifica un return, la función devuelve undefined por defecto. Las funciones sólo retornan un valor. Si queremos retornar más de uno los podemos agrupar en arrays o objetos.

1
2
3
4
5
6
7
8
9
10
function sinRetorno() {
  let mensaje = "Hola";
}

function conRetorno() {
  let mensaje = "Hola";
  return mensaje;
}

console.log(sinRetorno(),conRetorno()); 
1
undefined Hola

Invocación de funciones

Al usar paréntesis (), invocas a la función. Sin paréntesis, haces referencia al objeto que representa la función.

Las funciones son objetos

En JavaScript, las funciones son objetos de primera clase. Esto significa que pueden ser asignadas a variables, pasadas como argumentos y devueltas por otras funciones.

1
2
3
4
5
function multiplicar(x, y) {
  return x * y;
}
let operacion = multiplicar;
console.log(operacion(2, 3)); // 6
1
6

La capacidad de Javascript de tratar a las funciones como objetos le permite facilitar el uso de funciones de Callback y la programación funcional, que veremos en su capítulo.

¿Qué es un callback?

¿Qué es una función autoejecutable?

Una función autoejecutable es una función en JavaScript que se define y se ejecuta automáticamente en el momento de ser interpretada. Su estructura característica permite ejecutar una función de inmediato sin necesidad de llamarla explícitamente después de su definición.

La sintaxis básica de una función autoejecutable es la siguiente:

1
2
3
(function() {
    // Código de la función
})();

O bien:

1
2
3
4
(() => {
    // Código de la función
})();

Ejemplo con parámetros:

1
2
3
(function(nombre) {
    console.log(`Hola, ${nombre}!`);
})("Juan");

Declaración de funciones

Las funciones pueden ser declaradas de manera explícita. Este tipo de declaración se carga en tiempo de compilación, permitiendo su uso antes de la declaración (hoisting).

1
2
3
4
5
console.log(suma(2, 3)); // 5

function suma(a, b) {
  return a + b;
}
1
5

Las funciones también pueden ser definidas mediante expresiones. Este tipo de función se evalúa en tiempo de ejecución y no soporta hoisting.

1
2
3
4
5
let restar = function(a, b) {
  return a - b;
};

console.log(restar(5, 3)); // 2
1
2

Las expresiones de función pueden ser anónimas, es decir, no tener un nombre. Al no tener nombre, no se pueden invocar a si mismas, por lo que no se pueden hacer recursivas. Si no tienen nombre y son asignadas a una variable con una expresión de función, adquieren el nombre de la variable. Se suelen usar como funciones de “Callback”, aunque no es lo más recomendable porque luego complican la trazabilidad de los errores.

1
2
3
4
let dividir = function(a, b) {
  return a / b;
};
console.log(dividir(10, 2)); // 5
1
5

Funciones flecha

Una arrow function es una forma más abreviada/simplificada de escribir funciones anónimas. Esto las hace más complicadas de entender hasta que te acostumbras a su uso. Estas son su principales características:

  • Sintaxis Concisa: No es necesario usar la palabra clave function, return, ni utilizar llaves {} si la función solo tiene una expresión.
  • Constantes por Defecto: Se recomienda declarar funciones flecha utilizando const en lugar de var o let, ya que una vez asignadas, no pueden ser reasignadas a otro valor.
  • No tienen this propio: A diferencia de las funciones regulares, las funciones flecha no tienen su propio contexto this. En su lugar, heredan el this del contexto en el que fueron creadas.
  • No son hoisted: Las funciones flecha no son elevadas (hoisted) como las funciones tradicionales. Esto significa que no pueden ser invocadas antes de su declaración en el código.
  • Uso de {} y return: Si la función flecha tiene más de una línea de código o más de una instrucción, es necesario utilizar llaves {} y la palabra clave return explícitamente.
  • No pueden ser métodos: Debido a que no tienen su propio this, no pueden ser utilizadas como métodos en objetos.

A continuación te muestro como pasar de una función anónima a una función flecha:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Función tradicional
(function (a){
  return a + 100;
})

// Desglose de la función flecha

// 1. Elimina la palabra "function" y coloca la flecha entre el argumento y el corchete de apertura.
(a) => {
  return a + 100;
}

// 2. Quita los corchetes del cuerpo y la palabra "return" - el return está implícito.
(a) => a + 100;

// 3. Suprime los paréntesis de los argumentos
a => a + 100;

Ejemplo comparativo

Expresión de función tradicional:

1
2
3
var multiplicar = function(x, y) {
  return x * y;
};

Expresión de función flecha:

1
const multiplicar = (x, y) => x * y;

Las funciones flecha son muy usadas en la programación funcional. Pero también son criticadas por:

  • No tener una sintaxis coherente al necesitar (), {} o return en algunas circunstancias o ser demasiado cortas y ser confundidas con asignaciones.
  • No pueden ser usadas como métodos o constructor por no tener contexto (this).
  • Cuando retornan un objeto literal siempre necesitan {} y return, lo cual es molesto, a no ser que se ponga entre paréntesis.
1
const func = () => ({ foo: 1 });
  • No tienen el array arguments, aunque se puede usar la técnica de rest parameters como alternativa
1
const f = (...args) => args[0] + n;

Uso en Objetos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const persona = {
  nombre: 'Pepe',
  apellido: 'García',
  
  // Función regular
  consulta: function() {
    return `${this.nombre} ${this.apellido}`;
  },
  
  // Función flecha
  consultar: () => {
    // En este contexto, `this` no se refiere al objeto persona
    return `${this.nombre} ${this.apellido}`;
  }
};

console.log(persona.consulta());   // Salida: Pepe García
console.log(persona.consultar());  // Salida: undefined undefined

Salida:

1
2
Pepe García
undefined undefined
  • Función Regular: consulta es una función regular dentro del objeto persona. Al llamar a this.nombre y this.apellido, se refiere a las propiedades del objeto persona.
  • Función Flecha: consultar es una función flecha dentro del objeto persona. Debido a que las funciones flecha no tienen su propio this, this dentro de consultar no se refiere al objeto persona, sino al contexto global o a undefined en modo estricto (undefined en este caso).

(Voluntario) Lee el artículo Funciones Flecha.

Funciones anidadas

En JavaScript podemos anidar unas funciones dentro de otras. Es decir podemos programar una función dentro de otra función.

Cuando no tenemos funciones anidadas, cada función que definamos será accesible por todo el código, es decir serán funciones globales. Con las funciones anidadas, podemos encapsular la accesibilidad de una función dentro de otra y hacer que esa función sea privada o local a la función principal. No te recomiendo el reutilizar nombres de funciones con esta técnica, para evitar problemas o confusiones posteriores.

Ejemplo de una función anidada:

1
2
3
4
5
const calcularHipotenusa = (cateto1, cateto2) => {
   const calcularCuadrado = (x) => { return x * x; }
   return Math.sqrt(calcularCuadrado(cateto1) + calcularCuadrado(cateto2));
}
console.log(calcularHipotenusa(1, 2)); // Muestra por consola: 2.23606797749979 

Funciones predefinidas

A continuación te dejo una lista de funciones predefinidas, que se pueden utilizar a nivel global en cualquier parte de tu código de JavaScript. Estas funciones no están asociadas a ningún objeto en particular. Típicamente, estas funciones te permiten convertir datos de un tipo a otro tipo.

FunciónDescripción
decodeURI()Decodifica los caracteres especiales de una URL excepto: , / ? : @ & = + $ #
decodeURIComponent()Decodifica todos los caracteres especiales de una URL.
encodeURI()Codifica los caracteres especiales de una URL excepto: , / ? : @ & = + $ #
encodeURIComponent()Codifica todos los caracteres especiales de una URL.
escape()Codifica caracteres especiales en una cadena, excepto: * @ - _ + . /
eval()Evalúa una cadena y la ejecuta si contiene código u operaciones.
isFinite()Determina si un valor es un número finito válido.
isNaN()Determina cuando un valor no es un número.
Number()Convierte el valor de un objeto a un número.
parseFloat()Convierte una cadena a un número real.
parseInt()Convierte una cadena a un entero.
unescape()Decodifica caracteres especiales en una cadena, excepto: * @ - _ + . /

Bibliografía

Este artículo está licenciado bajo CC BY 4.0 por el autor.

Fundamentos de la programación con JavaScript

Tipos de datos en JavaScript