函数柯里化
#
概念柯里化的作用,是将一个有多个输入参数的函数,转换为只有一个输入参数的函数,并返回函数:以同样的方法,处理剩余的参数。
#
代码function curry(fn, ...args) { if(fn.length > args.length) { // 传入参数还未到达 return function(...arguments) { // 返回函数 return curry(fn, ...args, ...arguments); // 递归调用自己 } } else { return fn(...args); // 符合条件,返回最终函数 }}
// democonst add = (a, b, c) => a + b + c; // ①const curryAdd = curry(add); // ②curryAdd(1)(2)(3); // 6curryAdd(1, 2)(3); // 6curryAdd(1, 2, 3); // 6
#
分析看上面的demo代码,第①步,传入的函数有三个参数,而对函数柯里化后,curryAdd传入的参数可以每次传一个,一共传三次;也可以第一次传两个,第二次传一个;只要传递参数总长度是add的总长度即可。
第②步,对函数柯里化后,实际上curryAdd的值是一个函数,如下
function(...arguments) { return curry(fn, ...args, ...arguments);}
此处的...args
是空的,什么都没有,因为curry传入的参数只有一个add函数。
当调用到curryAdd(1)(2)(3)
时,返回值分别是以下函数
function(...arguments) { return curry(fn, 1, ...arguments);}
function(...arguments) { return curry(fn, 1, 2, ...arguments);}
function(...arguments) { return curry(fn, 1, 2, 3 ...arguments);}
add(1, 2, 3);
到第三个函数就会返回,此时参数的长度已经和add函数的输入参数对齐,此时调用add函数,返回结果。
#
感想以前也见过柯里化的一些东西,静不下心去分析。最近看了一些源码,觉得这种函数式编程在js中还是比较常见的。最近看到一篇文章,讲koa的洋葱圈模型,redux的实现,都是类似这种一层包一层的函数,将这些联系起来觉得还好理解一些。
written by rain.
20.08.04