L'article précédent a présenté l'implémentation de javascript
(currying) dans curry
la programmation fonctionnelle. Bien sûr, ce curry est un curry de paramètres limités, je l'essaierai quand j'en aurai. opportunité. Le genre de curry qui ajoute des paramètres infinis. Cette fois, nous parlons principalement de javascript
une autre fonction très importante dans la programmation fonctionnelle compose
Le rôle de la fonction compose
est de combiner des fonctions et de connecter des fonctions en série. plusieurs fonctions. La sortie d'une fonction est le paramètre d'entrée d'une autre fonction. Une fois que la première fonction commence à s'exécuter, l'exécution sera déduite comme des dominos.
Par exemple, si vous avez une telle exigence, vous devez saisir un nom. Ce nom est composé de firstName
, lastName
, puis afficher le nom en tout. lettres majuscules. Par exemple, si vous entrez jack
, smith
nous l'imprimerons, ‘HELLO,JACK SMITH’
.
Nous envisageons d'utiliser une combinaison de fonctions pour résoudre ce problème. Nous avons besoin de deux fonctions greeting
, toUpper
var greeting = (firstName, lastName) => 'hello, ' + firstName + ' ' + lastName var toUpper = str => str.toUpperCase() var fn = compose(toUpper, greeting) console.log(fn('jack', 'smith')) // ‘HELLO,JACK SMITH’
C'est l'utilisation générale de composer. attention à Il y a les points suivants : les paramètres de
compose
sont des fonctions, et ce qui est renvoyé est aussi une fonction
car en plus des paramètres acceptés de la première fonction, les paramètres acceptés par les autres fonctions sont les valeurs de retour de la fonction précédente, donc les paramètres de la fonction initiale sont 多元
, tandis que les valeurs acceptées des autres fonctions sont 一元
compsoe
La fonction peut accepter n'importe quel paramètre. Tous les paramètres sont des fonctions, et le sens d'exécution est 自右向左
La fonction initiale doit être placée dans le paramètre <🎜. >最右面
, la fonction initiale est fn('jack', 'smith')
, le résultat de l'exécution. est passé à greeting
en tant que paramètre, puis toUpper
est exécuté pour obtenir le résultat final. Par conséquent, permettez-moi de mentionner brièvement les avantages de composer. Si vous souhaitez ajouter une autre fonction de traitement, vous n'en avez pas besoin. pour modifier toUpper
. Il suffit d'exécuter un fn
. Par exemple, si nous voulons ajouter un autre compose
, il suffit de le faire. on voit qu’il est très pratique à maintenir et à développer. trim
var trim = str => str.trim() var newFn = compose(trim, fn) console.log(newFn('jack', 'smith'))
J'ai fini d'analyser l'exemple, conformément au principe fondamental, je souhaite toujours explorer comment
est implémenté. Tout d'abord, je vais expliquer comment je l'ai implémenté, et puis explorons à nouveau comment les deux principales bibliothèques de, sont implémentées. Le processus d'implémentation de compose
est très fonctionnel. javascript
lodash.js
Mon implémentationramda.js
ramda.js
Mon idée est que puisque la fonction s'exécute comme un domino, j'ai d'abord pensé à la récursion. Implémentons cela étape par étape
à la fonction renvoyée. compose
compose
len
Ce qu'il faut faire dans le corps de la fonction est d'exécuter en continu les fonctions dans f1
et d'utiliser le résultat de l'exécution de la fonction précédente comme paramètre d'entrée de la fonction d'exécution suivante.
var compose = function(...args) { var len = args.length return function f1() { } }
args
count
C'est l'idée. Bien sûr, ce n'est pas possible. Il n'y a pas de condition de sortie récursive lorsque la dernière fonction est exécutée, c'est-à-dire lorsque args
est <🎜. >. À l'heure actuelle, une chose à noter est qu'en cas de sortie récursive, le curseur
var compose = function(...args) { var len = args.length var count = len - 1 var result return function f1(...args1) { result = args[count].apply(this, args1) count-- return f1.call(null, result) } }
count
pour implémenter cette fonction 0
. Plus tard, j'ai découvert que la récursion peut être complètement implémentée en utilisant l'itération. Cela semble plus facile à comprendre en utilisant la fonction count
. En fait, c'est ainsi que
var compose = function(...args) { var len = args.length var count = len - 1 var result return function f1(...args1) { result = args[count].apply(this, args1) if (count <= 0) { count = len - 1 return result } else { count-- return f1.call(null, result) } } }
compose
L'idée d'implémenter while
lodash.js
lodash
On peut voir que l'implémentation originale de , mais elle fournit également lodash
de
var flow = function(funcs) { var length = funcs.length var index = length while (index--) { if (typeof funcs[index] !== 'function') { throw new TypeError('Expected a function'); } } return function(...args) { var index = 0 var result = length ? funcs[index].apply(this, args) : args[0] while (++index < length) { result = funcs[index].call(this, result) } return result } } var flowRight = function(funcs) { return flow(funcs.reverse()) }
, et à partir de cette ligne lodash
nous pouvons voir que le tableau peut être vide, ce qui montre qu'il est très strict. Ce que j'ai écrit manquait de cette gestion rigoureuse des exceptions. 从左到右
从右到左
ConclusionflowRight
数组
Cette fois, j'ai principalement présenté les principes et les méthodes d'implémentation de la fonction 参数序列
en programmation fonctionnelle. Pour des raisons d'espace, j'ai mis l'implémentation du code source var result = length ? funcs[index].apply(this, args) : args[0]
que je prévois. à analyser ci-dessous. Présentons-le dans un article. On peut dire que le
Ce qui précède est le contenu implémenté par compose dans la programmation fonctionnelle JavaScript. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !