什么是柯里化
定义:对一个多参数函数进行转换,转换成单一参数多次执行的函数
实际应用:接收一部分参数,返回一个函数接收剩余参数,接收足够参数后,执行原函数
示例:
const sum = (a, b, c) => {
return a + b + c;
};
console.log(sum(1, 2, 3)); //6
// 柯里化之后的
const currySum = (a) => {
return (b) => {
return (c) => {
return a + b + c;
};
};
};
console.log(currySum(1)(2)(3)); //6
柯里化的作用
降低通用性,提高适用性
写一个通用的Reg校验函数
const useRegCheck = (reg, str) => {
return reg.test(str);
};
// 校验电话号码
const checkPhone1 = useRegCheck(/^1[34578]\d{9}$/, "13888888888");
const checkPhone2 = useRegCheck(/^1[34578]\d{9}$/, "13412345678");
// 校验邮箱
const checkEmail1 = useRegCheck(
/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
"1239asd@gmail.com"
);
const checkEmail2 = useRegCheck(
/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
"123asd@163.com"
);
这样做确实是没问题的,但是每次都要复制粘贴一遍正则,代码不够简洁。
使用函数柯里化,只用定义好校验规则传入第一个参数,生成一个适用某个校验的函数,每次校验只用传入校验内容即可。
const curryUseRegCheck = (reg) => {
return (str) => {
return reg.test(str);
};
};
const checkPhone = curryUseRegCheck(/^1[34578]\d{9}$/);
const checkPhone1 = checkPhone("13888888888");
const checkPhone2 = checkPhone("13412345678");
const checkEmail = curryUseRegCheck(
/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
);
const checkEmail1 = checkEmail('123@163.com');
const checkEmail2 = checkEmail('12asd@gmail.com');
封装转换柯里化工具函数
const curry = (fn) => {
return function curryFn(...args) {
if (args.length >= fn.length) {
return fn(...args);
}
return function (...args2) {
return curryFn(...args.concat(args2));
};
};
};
验证一下
const sum = (a, b, c) => {
return a + b + c;
};
const currySum = curry(sum);
console.log(currySum(1)(2)(3)); //6
console.log(currySum(1, 2)(3)); //6
console.log(currySum(1)(2, 3)); //6
项目中可以使用lodash提供的函数柯里化。lodash中的curry提供了占位符的功能,可以改变参数参入的顺序,使用lodash本体作为占位符,被占位的参数作为下一个函数的参数传入。
const { curry } = _;
const currySum = curry(sum);
console.log(currySum(1)(2)(3)); //6
console.log(currySum(1, 2)(3)); //6
// lodash 中的curry还提供了占位符的功能
const toArr = (a, b, c, d) => {
return [a, b, c, d];
};
const curryToArr = curry(toArr);
console.log(curryToArr(1)(2)(3)(4)); // [1, 2, 3, 4]
console.log(curryToArr(1, _, 3)(2)(4)); // [1, 2, 3,4]