柯里化的定义
官方定义: 计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。
个人理解:创建一个函数,只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
柯里化的实现
function createCurry(func, args) {
//传入函数需要几个参数
var arity = func.length;
//存储要使用的参数
var args = args || [];
return function() {
//将arguments转换为数组
var _args = [].slice.call(arguments);
//将转化后的arguments数组和递归存储前的参数合并
[].push.apply(_args, args);
// 如果参数个数小于最初的func.length,则递归调用,继续收集参数
if (_args.length < arity) {
return createCurry.call(this, func, _args);
}
// 参数收集完毕,则执行func
return func.apply(this, _args);
}
}
可以看到createCurry就是我们实现的柯里化函数,接下来我们来使用它
function count(a,b,c,d){
return a+b
}
var countK = createCurry(count);
console.log(countK(1,1)(5,6)) // chrome执行后为:11
定义结合实现解读
我们可以看到执行结果为11,结合我们的定义“创建一个函数,只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数”,createCurry就是我们创建的函数。countK = createCurry(count)就是只传递给函数的一部分参数来调用它并返回一个函数,countK(1,1)(5,6)就是返回的函数我们来调用他来处理剩下的参数。
当我们调用createCurry并传入count时会记录参数数量和创建存储参数args数组并返回一个处理函数。当我们调用countK时countK(1,1)进入函数处理转换为数组并且与args进行合并,进行判断是否跟函数所需参数相等,不相等会进行递归再次返回处理函数。(5,6)进行调用与之前args数组合并为[5,6,1,1],判断是否跟函数所需参数相等,相等就会进行apply调用并返回结果。
可能描述起来有点啰嗦,可以copy下来代码 自己运行debug查看最为直观
当你看懂count例子后,我们再来一个例子。
function _map(array,func,) {
return array.map(func);
}
var _getNewArray = createCurry(_map);
var getNewArray = _getNewArray(function(item) {
return item * 100 + '%'
})
console.log(getNewArray([1, 2, 3, 0.12])) // chrome执行后为: ['100%', '200%', '300%', '12%'];
此栗子与之前相似,不过更贴近于我们的项目。我们只是把调用拆开了,第二次调用也是传入一个处理函数,等第三次调用时传入数据。
看到这里,两个栗子都能够理解之后,已基本掌握柯里化的使用。