Alex hace 6 años
¿Cuál es la diferencia entre una función de alto orden, closure, y currify?
** Tomado de una pregunta de "thepianist2" en Youtube **
He estado mirando este tutorial y gracias!, está bastante interesante, tengo una duda, ¿la diferencia entre una función de alto orden, closure, y currify cual es? ¿están asociadas de forma directa ya que sin la función de alto orden no se podría currificar?
Responder 1 respuesta
## Currying
**"Currying"** digamos que es un mecanismo que usamos para dividir o fragmentar una función que toma varios argumentos (parámetros) en varias funciones que toman sólo parte de estos argumentos, por ejemplo:
Imaginemos que tenemos una función que toma dos arrays, los invierte y luego los concatena:
```
function processArrays (arrayOne, arrayTwo) {
return [].concat(arrayOne.reverse(), arrayTwo.reverse());
}
console.log( processArrays([1,2,3], [4,5,6]) );
// Resultado esperado
// [3, 2, 1, 6, 5, 4]
```
Esta función le vamos a aplicar "Currying":
```
function processArrays (arrayOne) {
return function(arrayTwo) {
return [].concat(arrayOne.reverse(), arrayTwo.reverse());
}
}
```
Ahora podríamos invocar nuestra función así:
```
console.log( processArrays([1,2,3])([4,5,6]) );
// Resulatdo esperado
// [3, 2, 1, 6, 5, 4]
```
O bien "almacenar" nuestra función que "recordará" el parámetro arrayOne (aquí es donde podríamos decir que es una "closure").
```
var intermediateFunction = processArrays([1,2,3]);
```
Y luego podríamos ejecutar el siguiente paso, tantas veces como queramos, variando el parámetro arrayTwo:
```
console.log( intermediateFunction([4,5,6]) );
console.log( intermediateFunction([9,10,11]) );
console.log( intermediateFunction([24,25,26]) );
```
Este es un mecanismo muy poderoso que en JavaScript tenemos para crear funciones que sean "constructores" de funciones; la verdad algo muy genial.
## Higher-order functions
Por definición para que una función "sea llamada *higher-order function*" debe cumplir uno de dos requisitos:
- 1. Tener entre sus argumentos UNA o más funciones
- 2. O bien retornar una función como resultado
En nuestro caso la función `processArrays` cumple con el segundo criterio, es decir, regresa una función, por lo que podríamos llamarla una *higher-order function*. Por lo tanto, tu apreciación es correcta, SIN la *higher-order function* no podemos aplicar el concepto de *currify*.
## Closure
Una clausura o "closure" en JavaScript se forma con una función y un contexto llamado "lexical environment" en la que la función fue declarada.
Este "environment" o ambiente, tendrá todas las variables locales que estaban en el alcance cuando esta clausura fue generada.
Veamos un ejemplo práctico, imagina que estás creando unos botones para incrementar el tamaño de la fuente de texto de sitio web, tienes tres tamaños iniciales: small, medium y large con 12px, 16px y 30px respectivamente, y luego te gustaría que con un botón tu usuario vaya incrementando progresivamente el tamaño; entonces podríamos usar un código como el que sigue:
```
function setInitialFontSize(fontSize) {
return function(incrementForNewFontSize) {
return fontSize + incrementForNewFontSize;
};
}
```
En este caso nuestra "closure" nos permite que el valor 12, 16 y 30 "sean recordados" gracias a ese "lexical environment".
```
var increaseSmallSize = setInitialFontSize(12); // font-size: 12px is "small"
var increaseMediumSize = setInitialFontSize(16); // font-size: 16px is "medium"
var increaseLargeSize = setInitialFontSize(30); // font-size: 30px is "large"
console.log ( 'New font-size in px: ', increaseSmallSize(2) ); // New font-size in px: 14
console.log ( 'New font-size in px: ', increaseMediumSize(2) ) // New font-size in px: 16
console.log ( 'New font-size in px: ', increaseLargeSize(2) ) // New font-size in px: 32
```
> Por lo tanto, podemos resumir que para poder aplicar "currying" en JavaScript usaremos una *higher-order function* que creará "closures" por cada "lexical environment" que se genere.
Saludos.
Por favor inicia sesión para participar en esta pregunta