柯里化思想结合闭包解题与es6的部分特性讲解
柯里化(Currying)
柯里化(Currying)
是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
简单来说,就是将一个多参数的函数拆分成一系列单参数函数的组合。
柯里化的优点
- 提高函数的灵活性和复用性:可以根据不同的需求逐步构建参数。
- 延迟执行:可以先准备好部分参数,在合适的时候再提供其他参数来执行函数。
- 参数定制:更方便地对函数的参数进行定制和组合。
柯里化思想的应用
- 函数组合:可以通过柯里化将多个简单函数逐步组合成更复杂的函数。
- 参数配置:方便对函数的参数进行灵活的配置和定制,适应不同场景需求。
- 延迟计算:先准备部分参数,在合适时机再完成计算。
- 创建特定功能的函数变体:基于柯里化可以快速生成具有特定参数设置的函数版本。
- 提高代码可读性和可维护性:使函数的调用和参数传递逻辑更加清晰直观。 以add函数为例:首先实现两数相加
正常来说,我们首先就是接收两个参数然后直接return和。但是这样存在一些问题,比如传入的类型可能不对导致程序崩溃、数据参数数量也不确定,导致程序健壮性弱
function add(a, b) {
// 存在的问题 数据类型,数据参数数量
if (arguments.length != 2) {
console.log('参数错误');
return;
}
if (typeof a != 'number' || typeof b != 'number') {
console.log('类型错误');
return;
}
return a + b;
}
console.log(add(1, 2));
因此我们加上了typeof做类型判断,但是这样还是存在参数不定的问题。
我们接下来的想法是调用一次函数,我们可以把这个值给保留下来
,例如:
// add2 = add(2)
// add2(4)=6
这样就自然而然的使用到闭包
的概念了。
function add() {
let sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return function () {
let newSum = 0;
for (let j = 0; j < arguments.length; j++) {
newSum += arguments[j];
}
return sum + newSum;
}
}
add2 = add(2)
console.log(add2);
console.log(add2(4));
通过这种方式,我们第一次调用,如果只传入一个值,则会得到0+这个值,保留sum,通过闭包传递给子函数,第一次调用返回了一个函数,接下来我们可以继续调用,这就是一种柯里化的思想(慢慢收集、延迟执行、提高函数的灵活性以及复用性)
但是我们注意到,这样子写是不是有点违背es6给我们带来的新风向?我们想把代码写的越来越简洁
。
- es6为我们带来了
箭头函数
- 但是箭头函数没有
arguments关键字
来获取参数,怎么办? - 箭头函数虽然没有arguments关键字,但是有
... rest运算符
const curry = (fn, ...args) =>
// console.log(args.length, fn.length);
args.length >= fn.length ? fn(...args) : (..._args) => curry(fn, ...args, ..._args)
// 原函数
const add = (x, y, z, m) => x + y + z + m;
const curryAdd = curry(add, 1)(2)(3)(4);
console.log(curryAdd);
在这份代码中我们能看到,我们首先使用了一个原函数add
,实现我们最初的想法(4数相加),因此这个可以作为原函数,另外,我们写了一个柯里化函数curry
,通过三元运算符判断
,传入的值是否为4个,如果满足四个
,直接调用原函数做add操作,否则就递归调用curry
继续收集参数。
注意点:
- 箭头函数没有arguments关键字,可以使用
rest运算符
- 箭头函数的函数体如果只有一行代码,省略花括号的情况下,相等于也
省去了return
- 应用currying柯里化思想,逐步收集参数,提升
程序的灵活性、复用性
最后
通过柯里化思想解题,将多参数函数转化为单参数函数组合
。我们以add函数为例子,展现了从传统的实现到闭包与currying的结合
,相信这种解题思想能为你在一些场景下带来帮助。
接下来我们又提到了es6的一些特性
,箭头函数的简洁性,局限性,再通过rest运算符
为柯里化带来一些便利,通过柯里化逐步收集参数,提升程序灵活性与复用性
。
转载自:https://juejin.cn/post/7379167443501482035