函数柯里化(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 ( 强大的工具函数库,比如 节流,防抖,深拷贝 ) 也是都支持柯里化。

参考文章三行代码实现 add(1)(2)(3)

 posted on 2021-03-29 22:09  kly99  阅读(1078)  评论(0)    收藏  举报