接下来马上开始WWH(what,why,how)
W——什么是柯里化
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。
——百度百科《柯里化》
下面说一点人话
用cfn(1)(2)(3)
来实现fn(1,2,3)
的效果
W——为什么要柯里化
把一个抽象函数(即只知道参数列表和返回类型的函数模版)作为参数送给另一个函数。这样实现了调用和实现的分离
解决了某些方法只接受一个参数的问题
H——怎么实现柯里化
重头戏开始
先来看一个简单的二元函数转一元函数的示例
// 接收一个函数,返回一个柯里化的函数
function curry(fn) {
return function (x) {
return function (y) {
return fn(x, y)
}
}
}
function add(x, y) {
return x + y
}
const cAdd = curry(add)
console.log('add方法-' + add(1, 2));
console.log('cAdd方法-' + cAdd(1)(2));
类似于在z=x+y中,先确定了x的值,然后下一步把y带入,计算出结果
再来看一个实际一点的用法
const arr = [
{
name: 'zhangsan',
age: 12
},
{
name: 'lisi',
age: 12
},
{
name: 'wangwu',
age: 12
},
]
const getObj = (name, item) => {
return item.name === name
}
const cfn = curry(getObj)
// console.log(cfn('lisi').toString());
let result = arr.filter(cfn('lisi'))
console.log(result);
这段代码中首先定义了一个对象数组,然后使用数组的filter方法来获取某个对象,getObj方法接收两个参数,返回一个boolean值,柯里化之后只需要接收一个参数,因为是在filter函数的回调函数中,所以会自动将数组中的每一项作为参数执行回调函数
这里可能会很难绕出来,打印一下cfn('lisi')
看一下
可以看到cfn('lisi')
就只是一个函数,参数y就是filter遍历时的item
这只是二元柯里化,那我要是好多参数怎么办,再写一个?几个参数套几层闭包?
当然有一劳永逸的方法
function curry(fn) {
const length = fn.length;
const curryFn = (args) => (arg) => {
const curryArgs = args.concat(arg);
if (curryArgs.length === length) {
return fn(...curryArgs);
}
return curryFn(curryArgs);
}
return curryFn([]);
}
试一下
GOOD!!!