Implémentation du curry
La synthèse de fonctions JS consiste à combiner plusieurs fonctions à paramètre unique en une fonction à paramètres multiples. Par exemple, si a (x) et b (x) sont combinés en a (b (x)), ils sont appelés collectivement f (a, b, x). Notez que a (x) et b (x) ici ne peuvent recevoir qu'un seul paramètre. Si vous recevez plusieurs paramètres, tels que a (x, y) et b (a, b, c), la synthèse des fonctions est plus gênante.
À ce stade, la fonction currying est utilisée. Le currying consiste à transformer une fonction multi-paramètres en une fonction à paramètre unique. Avec l'opération de currying, nous pouvons réaliser que toutes les fonctions ne reçoivent qu'un seul paramètre.
var add = function (x) { //柯里化
return function (y) {
return x + y;
}
}
console.log(add(2) (6)); //8,连续调用
//柯里化函数
function curry (fn) {
var _argLen = fn.length; //记录原始函数的形参个数
var _args = [].slice.call(arguments, 1); //把传入的第2个及以后参数转换为数组
function wrap () { //curry函数
//把当前参数转换为数组,与前面参数进行合并
_args = _args.concat([].slice.call(arguments));
function act () { //参数处理函数
//把当前参数转换为数组,与前面参数进行合并
_args = _args.concat([].slice.call(arguments));
//如果传入参数总和大于等于原始参数的个数,触发执行条件
if ((_argLen == 0 && arguments.length == 0) ||
(_argLen > 0 && _args.length >= _argLen)) {
//执行原始函数,并把每次传入参数传入进去,返回执行结果,停止curry
return fn.apply(null, _args);
}
return arguments.callee;
}
//如果传入参数大于等于原始函数的参数个数,即触发了执行条件
if ((_argLen == 0 && arguments.length == 0) ||
(_argLen > 0 && _args.length >= _argLen)) {
//执行原始函数,并把每次传入参数传入进去,返回执行结果,停止curry
return fn.apply(null, _args);
}
act.toString = function () { //定义处理函数的字符串表示为原始函数的字符串表示
return fn.toString();
}
return act; //返回处理函数
}
return wrap; //返回curry函数
}
Réalisation de la fonction de synthèse
Dans la programmation fonctionnelle JS, les opérations d'expression suivantes sont souvent observées.
a(b(c(x)));
Il s'agit d'un appel de fonction multicouche de "style chou", mais pas très élégant. Afin de résoudre le problème d'imbrication des appels de fonctions à plusieurs niveaux, nous devons utiliser la composition de fonctions. Le format de la syntaxe est le suivant:
var f = compose(a, b, c); //合成函数
f(x);
递归实现:
const compose = function (...funcs) {
let len = funcs.length,
count = len - 1,
result = null;
// 首先compse 返回的是一个函数
return function fn(...args) {
// 函数体里就是不断执行args函数,将上一个函数的执行结果作为下一个执行函数的输入参数,需要一个count来记录args函数列表的执行情况
result = args[count].apply(this, args);
console.log(result);
// 递归退出条件
if (count <= 0) {
count = len - 1;
} else {
count--;
return fn.call(null, result);
}
};
};
Implémentation itérative:
function compose(...fns) {
let isFirst = true;
return (...args) => {
return fns.reduceRight((result, fn) => {
if (!isFirst) return fn(result);
isFirst = false;
return fn(...result);
}, args);
};
}