Conceptos Esenciales en Programación Funcional con JavaScript

Mar 12 2023
La programación funcional es un paradigma que ha ganado popularidad en los últimos años debido a su capacidad para escribir código más modular, reutilizable y mantenible. JavaScript, al ser un lenguaje de programación versátil, también es adecuado para la programación funcional.
Conceptos de Programación Funcional en JavaScript

La programación funcional es un paradigma que ha ganado popularidad en los últimos años debido a su capacidad para escribir código más modular, reutilizable y mantenible. JavaScript, al ser un lenguaje de programación versátil, también es adecuado para la programación funcional. En este artículo, exploraremos conceptos esenciales en la programación funcional con JavaScript y cómo pueden ayudarlo a escribir mejor código:

  1. Funciones como ciudadanos de primera clase
  2. Funciones de orden superior
  3. Funciones puras
  4. Inmutabilidad
  5. recursividad

En la programación funcional, las funciones se tratan como ciudadanos de primera clase, lo que significa que pueden asignarse a variables, pasarse como argumentos a otras funciones y devolverse como valores. Este concepto es crucial en la programación funcional, ya que nos permite escribir código más modular y reutilizable.

Estos son algunos ejemplos de cómo las funciones se tratan como ciudadanos de primera clase en JavaScript:

  1. Asignación de funciones a variables:

const add = function(x, y) {
  return x + y;
}

2. Pasar funciones como argumentos:

Las funciones también se pueden pasar como argumentos a otras funciones. Esto permite un enfoque más modular de la programación, ya que nos permite reutilizar la misma función con diferentes entradas y salidas. Por ejemplo:

function greet(name, callback) {
  const message = "Hello, " + name + "!";
  callback(message);
}

function logMessage(message) {
  console.log(message);
}

greet("Sumit", logMessage); // Logs "Hello, Sumit!"

3. Devolver funciones como valores:

Las funciones también se pueden devolver como valores de otras funciones. Esto permite técnicas más avanzadas como cierres y curry. Por ejemplo:

function add(x) {
  return function(y) {
    return x + y;
  };
}

const addFive = add(5);
console.log(addFive(3)); // Logs 8

✓ Funciones de orden superior

Las funciones de orden superior son funciones que toman otras funciones como argumentos o devuelven funciones como valores. Nos permiten escribir código más abstracto y de propósito general que se puede aplicar a diferentes casos de uso. Algunas funciones comunes de orden superior en JavaScript son map(), filter() y reduce().

Estos son algunos ejemplos de funciones de orden superior en JavaScript:

  1. Array.prototipo.mapa():

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(function(num) {
  return num * 2;
});
console.log(doubled); // Logs [2, 4, 6, 8]

2. Matriz.prototipo.filtro():

El filter()método es otra función de orden superior que toma una función de devolución de llamada como argumento y devuelve una nueva matriz con solo los elementos que pasan la prueba especificada en la devolución de llamada. Por ejemplo:

const numbers = [1, 2, 3, 4];
const even = numbers.filter(function(num) {
  return num % 2 === 0;
});
console.log(even); // Logs [2, 4]

3. Función.prototipo.bind():

El bind()método es una función de orden superior que devuelve una nueva función con un thisvalor específico y argumentos iniciales. A menudo se usa para crear una nueva función con un contexto específico o para crear una función aplicada parcialmente. Por ejemplo:

const person = {
  firstName: "Sumit",
  lastName: "Saha",
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
};

const logName = function(greeting) {
  console.log(greeting + " " + this.fullName());
};

const boundLogName = logName.bind(person, "Hello");
boundLogName(); // Logs "Hello Sumit Saha"

Estos son solo algunos ejemplos de las muchas funciones de orden superior disponibles en JavaScript. Mediante el uso de funciones de orden superior, puede escribir código más genérico y reutilizable que se puede aplicar a diferentes casos de uso.

✓ Funciones puras

Las funciones puras son funciones que no tienen efectos secundarios, lo que significa que no modifican ningún estado externo o variables fuera de su alcance. Siempre devuelven la misma salida para la misma entrada, lo que los hace deterministas. Las funciones puras son esenciales en la programación funcional, ya que promueven la previsibilidad, la capacidad de prueba y la capacidad de mantenimiento del código.

Aquí hay algunos ejemplos de funciones puras en JavaScript:

  1. Función de suma:
  2. function add(a, b) {
      return a + b;
    }
    

function concatenateArrays(arr1, arr2) {
  return arr1.concat(arr2);
}

3. Función de formato de fecha:

function formatDate(date) {
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  return `${year}-${month}-${day}`;
}

4. Función de capitalización de cadenas:

function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

En general, las funciones puras son funciones que no tienen efectos secundarios y siempre devuelven el mismo resultado para la misma entrada. Son predecibles y fáciles de razonar, lo que los hace ideales para escribir código mantenible y reutilizable.

✓ Inmutabilidad

La inmutabilidad es un concepto que implica evitar modificar estructuras de datos o variables una vez creadas. En lugar de cambiar un objeto o una matriz, creamos uno nuevo con los cambios deseados. Este enfoque evita efectos secundarios no deseados y hace que el código sea más predecible y más fácil de razonar.

Aquí hay algunos ejemplos de inmutabilidad en JavaScript:

  1. Usando el operador de propagación para crear una nueva matriz u objeto:
  2. const arr1 = [1, 2, 3];
    const arr2 = [...arr1, 4];
    // arr1 is still [1, 2, 3], arr2 is [1, 2, 3, 4]
    
    const obj1 = { a: 1, b: 2 };
    const obj2 = { ...obj1, c: 3 };
    // obj1 is still { a: 1, b: 2 }, obj2 is { a: 1, b: 2, c: 3 }
    

const arr1 = [1, 2, 3];
const arr2 = arr1.concat(4);
// arr1 is still [1, 2, 3], arr2 is [1, 2, 3, 4]

3. Usar Object.assign()para crear un nuevo objeto:

const obj1 = { a: 1, b: 2 };
const obj2 = Object.assign({}, obj1, { c: 3 });
// obj1 is still { a: 1, b: 2 }, obj2 is { a: 1, b: 2, c: 3 }

4. Uso Object.freeze()para evitar la modificación de un objeto:

const obj1 = Object.freeze({ a: 1, b: 2 });
obj1.c = 3;
// obj1 is still { a: 1, b: 2 }, the assignment is ignored

En general, la inmutabilidad significa que los datos no se modifican directamente, sino que se crean nuevas copias cuando se realizan cambios. Esto puede ayudar a prevenir efectos secundarios no deseados y hacer que el código sea más predecible y mantenible.

✓ Recursividad

La recursividad es una técnica en la que una función se llama a sí misma para resolver un problema. Es una poderosa herramienta en programación funcional, ya que nos permite resolver problemas complejos dividiéndolos en otros más pequeños y simples. Sin embargo, la recursividad puede ser complicada de usar, ya que puede provocar errores de desbordamiento de pila y problemas de rendimiento si no se usa correctamente.

Aquí hay algunos ejemplos de recursividad en JavaScript:

  1. Función factorial:
  2. function factorial(n) {
      if (n === 0) {
        return 1;
      } else {
        return n * factorial(n - 1);
      }
    }
    
    factorial(5); // returns 120 (5! = 5 * 4 * 3 * 2 * 1)
    

function sum(arr) {
  if (arr.length === 0) {
    return 0;
  } else {
    return arr[0] + sum(arr.slice(1));
  }
}

sum([1, 2, 3, 4, 5]); // returns 15 (1 + 2 + 3 + 4 + 5)

3. Función de Fibonacci:

function fibonacci(n) {
  if (n === 0 || n === 1) {
    return n;
  } else {
    return fibonacci(n - 1) + fibonacci(n - 2);
  }
}

fibonacci(6); // returns 8 (0, 1, 1, 2, 3, 5, 8)

La recursividad puede ser una herramienta poderosa para resolver problemas que involucran patrones o estructuras repetitivas. Sin embargo, también puede provocar problemas de rendimiento y errores de desbordamiento de pila si no se implementa con cuidado. Es importante comprender el concepto de recursividad y usarlo con prudencia en su código.

Conclusión

En conclusión, la programación funcional es un paradigma importante que puede ayudarlo a escribir código más modular, reutilizable y mantenible. Al comprender conceptos esenciales como funciones como ciudadanos de primera clase, funciones de orden superior, funciones puras, inmutabilidad y recursividad, puede comenzar a escribir código más funcional en JavaScript. La programación funcional no es la única forma de escribir un buen código, pero es una herramienta poderosa que puede ayudarlo a resolver problemas complejos y hacer que su código sea más predecible y más fácil de razonar.