柯里化
柯里化(Haskell Brooks Curry)
- 使用柯里化解决硬编码问题
//function checkAge(age){
//let min=18;
//return age>=min;
//}
//普通纯函数
//function checkAge(min,age){
//return age>=min;
//}
//checkAge(18,24);
//checkAge(18,20);
//checkAge(20,30);
//函数的柯里化
function checkAge(min){
return function(age){
return age>=min;
}
}
let checkAge18=checkAge(18);
let checkAge20=checkAge(20);
console.log(checkAge18(20));
console.log(checkAge18(24));
//es6 写法
let checkAge=min=>(age=>age>=min);
let checkAge18=checkAge(18);
let checkAge20=checkAge(20);
console.log(checkAge18(20));
console.log(checkAge18(24));
柯里化(currying)
- 当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变)
- 然后返回一个新的函数接收剩余的参数,返回结果
Lodash中的柯里化
- .curry(func)
- 功能:创建一个函数,该函数接收一个或多个func的参数,如果func所需要的参数都被提供则执行执行的结果。否则继续返回该函数并等待接收剩余的参数。
- 参数:需要柯里化的函数
- 返回值:柯里化后的函数
//lodash中的curry基本使用
const _=require('lodash');
//柯里化可以把任意多个参数的函数转化为一个一元参数的函数
function 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));
柯里化案例
//提取空白字符
''.match(/\s+/g)
//提取数字
''.match(/\d+/g)
function match(reg,str){
return str.match(reg);
}
柯里化处理
const _=require('lodash');
const match=_.curry(function(reg),str){
return str.match(reg);
})
const haveSpace=match(/\s+/g);
const haveNumber=match(/\d+\g);
console.log(haveSpace('Hello world'));
console.log(haveNumber('abc'));
过滤数组
const _=require('lodash');
const match=_.curry(function(reg),str){
return str.match(reg);
})
const haveSpace=match(/\s+/g);
const haveNumber=match(/\d+\g);
const filter=_.curry(function(func,array){
return array.fiter(func);
})
console.log(filter(haveSpace,['John Connor','John_Donne']));
const findSpace=filter(haveSpace);
console.log(findSpace(['John Connor','John_Donne']));
柯里化实现原理
模拟实现lodash中的curry方法
function 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));
function curry(func){
return function curriedFn(...args){
//判断实参和形参的个数
if(args.length<func.length){
return function(){
return curriedFn(...args.concat(Array.from(arguments)));
}
}
return func(...args);
}
}
总结
- 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数
- 这是一种对函数参数的‘缓存’
- 让函数变得更灵活,让函数的粒度更小
- 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能。