函数柯里化

141 阅读3分钟
  • 柯里化是什么
  • 例子
  • 柯里化作用
  • 高级柯里化实现

柯里化是什么

柯里化是一种处理函数的高级技术。它不仅用于JavaScript,也用于其他语言。它是一种形态变化,将f(a, b, c)变成f(a)(b)(c)的形式。函数柯里化不会调用方法,只会转化它

例子

我们将创建一个帮助函数curry(f),将有两个参数的f(a,b)方法转化成用f(a)(b)运行的方法

function curry(f) { // curry(f) does the currying transform
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}
// usage
function sum(a, b) {
  return a + b;
}

let curriedSum = curry(sum);

alert( curriedSum(1)(2) ); // 3

如您所见,实现非常简单:它只是两个包装器。

1、curry(func)的结果是一个包装函数(a)

2、当它curriedSum(1)调用时,参数保存在词法环境中,新的包装器是返回function(b)。然后这个包装器用2作为参数调用,并将调用传递给原始方法sum

柯里化作用

固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数。

  1. 提高了代码的合理性,它突出一种思想---降低适用范围,提高适用性。

  2. 对于一个已有函数,对其约定好其中的某些参数输入,然后生成一个更有好的、更符合业务逻辑的函数。

柯里化(currying),我们可以这么理解:

柯里化就是一个函数在参数没给全时返回另一个函数,返回的函数的参数正好是余下的参数。比如:你制定了x和y, 如2的3次方,就返回8, 如果你只制定x为2,y没指定, 那么就返回一个函数:2的y次方, 这个函数只有一个参数:y。这样就非常容易理解吧

举个例子:你有一家商店,然后你想给你的优惠顾客10%的折扣

// 折扣
function discount(discount, price) {  return price * discount}

let totalPrice1 = discount(0.1, 200)
let totalPrice2 = discount(0.1, 400)
// 柯里化函数function curry(fn) {  return function(a) {    return function(b) {      return fn(a, b)    }  }}

// 我们将折扣的计算柯里化之后,就不用每次都写那0.10。每次针对商品价格打折就可以
// 提前把易变因素,传参固定下来,生成一个更明确的应用函数
let curryResult = curry(discount)
let priceDiscount = curryResult(0.1) // 固定折扣
let totalPrice1 = discount(200) // 商品折扣后价格
let totalPrice2 = discount(400) // 商品折扣后价格

同时currying函数, 可以延迟到最后一刻才一起计算, 好处不言而喻, 在很多场合可以避免无谓的计算, 节省性能, 也是实现惰性求值的一种方案

高级柯里化实现

利用递归思想

function curry(func) {
  return function curried(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2));
      }
    }
  };
}

例子:

function sum(a, b, c) {
  return a + b + c;
}

let curriedSum = curry(sum);

alert( curriedSum(1, 2, 3) ); // 6, still callable normally
alert( curriedSum(1)(2,3) ); // 6, currying of 1st arg
alert( curriedSum(1)(2)(3) ); // 6, full currying

参考链接:

javascript.info/currying-pa…

www.jianshu.com/p/822c4bfeb…

cloud.tencent.com/developer/a…