函数柯里化(curry)是函数式编程里面的概念。函数柯理化是指 每次调用函数时,它先接受一部分参数,并返回一个函数,然后再传递剩下的一部分参数,返回一个函数,直到传递所有参数为止 。
柯理化有什么意义呢?
主要有三个作用: 参数复用、提前返回和 延迟执行
在文章最后解释这三个作用。
柯理化函数的例子,比如:
add(1)(2)
const add = x => y => x + y; add(1)(2);add(1)(2)(3)
const add = x => y => z => x + y + z; console.log(add(1)(2)(3));
上面的比较简单,只是一个一个参数传入,那么但一次传入两个参数,三个参数呢?
比如: add(1, 2)(3), add(1)(2, 3)
基于上面的情况,实现一个简单柯理化函数的思路(结合下面代码):
- carry是用来生成 fn 函数成为柯理化函数的工具函数,add1 是我们要让其成为柯理化函数的目标函数(也就是 fn)
- 根据传入的参数个数 (args.length) 是否大于等于原函数所需参数个数 (fn.length) ,如果是,则执行当前函数;否则返回一个函数(carry函数)
// carry是用来生成 fn 函数成为柯理化函数的函数, function carry(fn, ...args) { //传入的参数个数 (args.length) 是否大于等于原函数所需参数个数 (fn.length) ,如果是,则执行当前函数;否则返回一个函数 if (args.length >= fn.length) { return fn(...args); } else { return function (..._args) { return carry(fn, ..._args, ...args) }; } } function add1(x, y, z) { return x + y + z; } let add = carry(add1); console.log(add(1, 2, 3)); console.log(add(1, 2)(3)); console.log(add(1)(2, 3));
最后,我们来解释一下作用
比如,我们有一个柯理化函数 add(最多传入3个参数),那么 add(1, 2)(m) 的结果就是 1+2+m,我们只需要这样做:
令 fn_1_2 = add(1, 2) ,之后 fn_1_2(m) 就只需直接传入一个值 m,不需要传入 1和2,达到复用 1和2 这两个参数了
let fn_1_2 = add(1)(2); console.log(fn_1_2(3)) // 6 console.log(fn_1_2(4)) // 7这就是参数复用,而 提前返回 和 延迟执行 也很好理解,因为每次调用函数时,它只接受一部分参数,并返回一个函数(提前返回),直到(延迟执行)传递所有参数为止。
Ramda ( 函数式编程风格的函数库 )中的所有函数都支持柯里化 , lodash ( 强大的工具函数库,比如 节流,防抖,深拷贝 ) 也是都支持柯里化。
posted on
浙公网安备 33010602011771号