柯里化,lodash.curry的原理理解

482 阅读2分钟

柯里化

在我理解,是闭包的进一步使用,他的目的

1、让我们给一个函数传递较少的参数得到一个已经记住了某些固定函数的新函数。

使用闭包记住传入的内容,进行缓存,返回一个回调函数,提供后续调用。而后续调用可以一直使用前一次调用的缓存,直到达到返回结果的条件。 2、对函数参数的缓存

纯函数、闭包的运用 3、让函数更灵活、粒度更小

4、使多元函数转换成一元函数,可以组合使用函数产生强大功能

多元 === 多个参数

lodash 本身封装了一套柯里化方法,他的作用是实现存储一个函数,在后续调用的时候,传入既定参数,待既定参数的数量等于函数需要的入参数时,返回结果:

如下,传入一个计算总和的函数,_.curry将getSum函数缓存起来,返回一个函数供curried的调用,在后续curried的多次调用,如果总的实参不等于getSum所需要的形参数量,那就会一直返回同一个回调函数,等待下一次调用。直到数量相同,即返回结果;

const _ = require('lodash');
const getSum = (a, b, c) => {
 return a + b + c;
};

const curried = _.curry(getSum);
console.log(curried(1,2,3)); // 6
console.log(curried(1,2)(3)); // 6
console.log(curried(1)(2)(3)); // 6

其原理实现:

第一步,实现一个函数的封装,如下:

curryFn实现了对函数进行缓存,在后续调用curried的时候,会将入参传给先前缓存的getSum函数,并返回结果。

const getSum = (a, b, c) => {
 return a + b + c;
};

const curryFn = (func) => {
 return (...args) => {
 return func(...args);
    }
};

const curried = curryFn(getSum); console.log(curried(1)); 第二步,实现函数入参的缓存,第一步只做到了函数缓存,调用curried的时候,必须传入等同的入参才能正常运行。但是柯里化的目的是为了做到缓存,直至达到请求目的。

所以在此基础上,

增加判断实参与形参的数量是否一致,如果一致,则达到了请求目的,返回结果。

反之,则将实参继续缓存,返回一个curriedFn函数,等待下一次调用。

function curry (func) {
 const curriedFn = (...args) => {
 // 判断实参、形参个数
 if (args.length < func.length) {
 return (...args1) => {
 // 这个func用来获取arguments
 // from数组转换
 return curriedFn(...args.concat(Array.from(args1)));
            }
        }
 return func(...args);
    }
 return curriedFn;
}

const getSum = (a, b, c) => {
 return a + b + c;
};
const curried = curry(getSum);

console.log(curried(1, 2, 3));
console.log(curried(1)(2, 3));
console.log(curried(1)(2)(3));
文章内容输出来源:拉勾教育Java高薪训练营;