Funciones de orden superior en JavaScript: ¿qué es?

Le presentamos una traducción de un artículo de Sukhjinder Arora publicado en Bits and Pieces . Descubra debajo del gato acerca de las funciones de orden superior en JavaScript y algunas otras funciones integradas en este lenguaje.


Foto de NESA por los creadores de Unsplash

Al aprender la programación de JavaScript, probablemente se encontró con el concepto de funciones de orden superior . Aunque este concepto puede parecer intimidante, en realidad no es tan complicado.

Gracias a la capacidad de trabajar con funciones de orden superior, JavaScript es adecuado para la programación funcional.

Las funciones de orden superior son comunes en JavaScript. Si trabajó con él durante un tiempo, es muy probable que haya utilizado tales funciones sin siquiera darse cuenta.

Para obtener una imagen completa de las funciones de orden superior, primero debe comprender qué son la programación funcional y las funciones de primera clase .

Consejo : la reutilización de las funciones de JavaScript a menudo conduce a duplicados. Para evitar esto, use Bit (GitHub) . Puede encontrar fácilmente nuevas funciones, compartirlas y volver a aplicarlas con cambios mínimos de administración. Pruébalo, no seas tímido.

¿Qué es la programación funcional?


Sin entrar en detalles, la programación funcional es la programación en la que algunas funciones se pasan como argumentos a otras funciones y devuelven terceras funciones como valores. En la programación funcional, pensamos y operamos con funciones.

La programación funcional se realiza en lenguajes como JavaScript, Haskell, Clojure, Scala y Erlang.

¿Cuáles son las características de primera clase?


Al aprender a trabajar con JavaScript, lo más probable es que haya escuchado que para él, las funciones son ciudadanos de primera clase. El hecho es que en JavaScript, como en cualquier otro lenguaje de programación funcional, las funciones son objetos.

Específicamente para JavaScript, las funciones son objetos de un tipo especial (objetos de Function o functores). Por ejemplo:

 function greeting() { console.log('Hello World'); } // Invoking the function greeting(); // prints 'Hello World' 

Para mostrar que las funciones en JavaScript son objetos, podemos hacer algo como esto:

 // We can add properties to functions like we do with objects greeting.lang = 'English'; // Prints 'English' console.log(greeting.lang); 

Nota: aunque lo anterior funciona bien en JavaScript, no debe abusar de él. No puede asignar propiedades aleatorias a los functores: es mejor usar objetos normales.

En JavaScript, todo lo que puede hacer con otras entidades, como un objeto, una cadena o un número, se aplica a las funciones. Se pueden pasar, incluso como argumentos a otras funciones (luego se denominan funciones de devolución de llamada o funciones de devolución de llamada), asignarlas a variables, etc. Es por eso que las funciones de JavaScript se denominan funciones de primera clase.

Asignación de funciones a variables


JavaScript le permite asignar funciones a variables. Por ejemplo:

 const square = function(x) { return x * x; } // prints 25 square(5); 

También se pueden transmitir. Por ejemplo:

 const foo = square; // prints 36 foo(6); 

Pasar funciones como argumentos


Podemos pasar funciones como argumentos a otras funciones. Por ejemplo:

 function formalGreeting() { console.log("How are you?"); } function casualGreeting() { console.log("What's up?"); } function greet(type, greetFormal, greetCasual) { if(type === 'formal') { greetFormal(); } else if(type === 'casual') { greetCasual(); } } // prints 'What's up?' greet('casual', formalGreeting, casualGreeting); 

Entonces, ahora que sabemos qué son las funciones de primera clase, pasemos a las funciones de orden superior en JavaScript.

Funciones de orden superior


Las funciones de orden superior son funciones que funcionan con otras funciones, tomando una función como argumento o devolviendo una función como resultado.

Ejemplos de funciones de orden superior que ya están integradas en el lenguaje son Array.prototype.map , Array.prototype.filter y Array.prototype.reduce .

Funciones de orden superior en acción


Veamos algunos ejemplos de funciones integradas de orden superior y compárelas con soluciones en las que no se utilizan funciones de orden superior.

Array.prototype.map
El método map() crea una nueva matriz con el resultado de llamar a la función aprobada para cada elemento de la matriz inicial. El método map() toma cada valor de la función de devolución de llamada y crea una nueva matriz con estos valores.

La función de devolución de llamada pasada al método map() toma tres argumentos: element , index y array .

Considere esto con algunos ejemplos.

Ejemplo no 1
Supongamos que tenemos una matriz de números, y de ella queremos crear una nueva matriz en la que se duplique cada número de la matriz inicial. ¿Cómo podemos resolver este problema con y sin una función de orden superior?

Sin una función de orden superior:

 const arr1 = [1, 2, 3]; const arr2 = []; for(let i = 0; i < arr1.length; i++) { arr2.push(arr1[i] * 2); } // prints [ 2, 4, 6 ] console.log(arr2); 

Usando la función de map orden superior:

 const arr1 = [1, 2, 3]; const arr2 = arr1.map(function(item) { return item * 2; }); console.log(arr2); 

El código puede hacerse aún más corto usando la función de flecha.

 const arr1 = [1, 2, 3]; const arr2 = arr1.map(item => item * 2); console.log(arr2); 

Ejemplo no 2
Digamos que tenemos una matriz que contiene los años de nacimiento de varias personas, y de ella queremos crear una nueva matriz en la que se encuentren sus edades.

Sin una función de orden superior:

 const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = []; for(let i = 0; i < birthYear.length; i++) { let age = 2018 - birthYear[i]; ages.push(age); } // prints [ 43, 21, 16, 23, 33 ] console.log(ages); 

Usando la función de map orden superior:

 const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = birthYear.map(year => 2018 - year); // prints [ 43, 21, 16, 23, 33 ] console.log(ages); 

Array.prototype.filter
El método filter() crea una nueva matriz con todos los elementos aprobados en la prueba especificada en la función aprobada. La función de devolución de llamada pasada a filter() toma tres argumentos: element , index y array .

Considere esto con algunos ejemplos.

Ejemplo no 1
Imagine que tenemos una matriz que contiene objetos con las propiedades "nombre" y "edad". A partir de él, queremos crear una nueva matriz en la que solo se indiquen adultos (a partir de dieciocho años).

Sin una función de orden superior:

 const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = []; for(let i = 0; i < persons.length; i++) { if(persons[i].age >= 18) { fullAge.push(persons[i]); } } console.log(fullAge); 

Usando la función de filter orden superior:

 const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = persons.filter(person => person.age >= 18); console.log(fullAge); 

Array.prototype.reduce
El método reduce aplica una función a cada valor de la matriz, reduciéndolo a un solo valor. El método reduce toma dos argumentos:
  1. función de devolución de llamada para ser procesada;
  2. parámetro opcional initialValue (primer argumento en la primera llamada de función).

La función de devolución de llamada toma cuatro argumentos: accumulator , currentValue , currentIndex , sourceArray .

Si se pasó el parámetro initialValue , el argumento del accumulator será igual al argumento initialValue y el argumento currentValue el primer elemento de la matriz.

Si no se pasó el parámetro initialValue , el argumento del accumulator será igual al primer elemento de la matriz, y el segundo elemento de la matriz se tomará como el argumento currentValue .

Ejemplo no 1
Supongamos que necesitamos encontrar la suma de los números en una matriz.

El uso de una función de orden superior reduce :

 const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }); // prints 25 console.log(sum); 

Cada vez que se aplica una función de devolución de llamada a cada valor de la matriz, el argumento del accumulator guarda el resultado de la acción anterior devuelta por la función, y currentValue toma el siguiente valor de la matriz. Al finalizar, el resultado se almacena en la sum variable.

Además, podemos pasar a esta función el valor inicial:

 const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }, 10); // prints 35 console.log(sum); 

Sin una función de orden superior:

 const arr = [5, 7, 1, 8, 4]; let sum = 0; for(let i = 0; i < arr.length; i++) { sum = sum + arr[i]; } // prints 25 console.log(sum); 

Como puede ver, con la ayuda de una función de orden superior, el código puede hacerse más ordenado, más corto y más amplio.

Crea tu propia función de orden superior


Hasta este punto, hemos considerado varias funciones de orden superior integradas en el lenguaje. Es hora de crear su propia función de orden superior.

Imagine que JavaScript no tendría su propio método de map . Podríamos construirlo nosotros mismos, creando así nuestra propia función de un orden superior.

Digamos que tenemos una matriz de cadenas, y de ella queremos crear una matriz de integrales en la que cada elemento representará la longitud de la cadena desde la matriz inicial.

 const strArray = ['JavaScript', 'Python', 'PHP', 'Java', 'C']; function mapForEach(arr, fn) { const newArray = []; for(let i = 0; i < arr.length; i++) { newArray.push( fn(arr[i]) ); } return newArray; } const lenArray = mapForEach(strArray, function(item) { return item.length; }); // prints [ 10, 6, 3, 4, 1 ] console.log(lenArray); 

En el ejemplo anterior, creamos una función de orden superior mapForEach , que toma una matriz y una función de devolución de llamada fn como argumentos. Esta función se aplica cíclicamente a cada elemento de la matriz y llama a la función de devolución de llamada fn como parte de la newArray.push función newArray.push en cada iteración.

La función de devolución de llamada fn toma el elemento actual de la matriz inicial y devuelve el valor de longitud de este elemento, que se almacena dentro de la nueva newArray . Una vez completada la iteración, la matriz newArray devuelve como resultado y se asigna a la matriz lenArray .

Conclusión


Aprendimos qué son las funciones de orden superior y examinamos algunas de las funciones integradas en el lenguaje. También aprendimos cómo crear sus propias funciones de orden superior.

En resumen, las funciones de orden superior funcionan como funciones regulares, pero tienen la capacidad adicional de recibir otras funciones como argumento y devolverlas como resultado.

Eso, de hecho, es todo. Si encuentra útil este artículo, también puede seguirme en Medium y en Twitter . ¡Siéntase libre de comentar si tiene alguna pregunta! Estaré encantado de ayudar. :)

Source: https://habr.com/ru/post/es428612/


All Articles