柯理化定义
有人说这是工厂模式,因为这个确实是通过一个函数生成另一个可用的函数,有人说这是建造者模式,因为可以多层套用,建造出自己想要的函数实例。 举个例子
// 普通加法
function sum(a,b){
return a+b
}
sum(1,2)
function ksum (a){
return (b)=>{
return a+b
}
}
const sum1 = ksum(1)
sum1(2)
例子里,使用柯理化函数就能去掉一个固定的入参,当然,前提是固定的入参,但是这就有一个问题,如果是一层封装,这样写还简单,如果是多层就不好写了,冗余
function sum2(a){
return (b)=>(c)=>(d)=>(e)=>a+b+c+d+e
}
sum2(1)(2)(3)(4)(5)
不美观了,所以需要一个函数来进行函数向柯理化的转换,这样就不用重复代码了,当然,从定义上看,这肯定是一个递归函数
function curry(fn, args) {
var length = fn.length;
var args = args || [];
console.log('柯理化生成函数执行', args, fn.length);
return function () {
newArgs = args.concat(Array.prototype.slice.call(arguments));
console.log('arguments', [...arguments], newArgs, args);
if (newArgs.length < length) {
// 这一步是保证参数全都柯理化完成
return curry.call(this, fn, newArgs);
} else {
console.log('柯理化最后一步,执行');
return fn.apply(this, newArgs);
}
};
}
//需要被柯里化的函数
function multiFn(a, b, c) {
return a * b * c;
}
//multi是柯里化之后的函数
var multi = curry(multiFn);
console.log(multi(2)(3)(4));
console.log(multi(2, 3, 4, 5));
console.log(multi(2, 6)(3, 4, 5));
console.log(multi(2, 3)(4));
其实这段代码我觉得并没有什么用,柯理化的作用体现的不是很明显
柯理化的应用场景
为了减少重复传递的不变参数,比如写一个手机号校验函数
function valiPhone(reg, phone){
if(phone && reg.test(phone)){
return Promise.resolve()
}
return Promise.reject('x')
}
这样子每次都需要传入reg(其实这个例子不太好) 所以我们可以柯理化(抽象出)函数,一个生成test工具
function curryTest(reg){
return (str)=>{
reg.test(str)
}
}
const valiPhone = curryTest(/\d/)
这样也增加了可拓展性