定义:当一个函数有多个形参需要接受时,先传递一部分参数,此时返回一个函数,等待接受剩余的参数,并会缓存之前的传递的参数;
如图:
/**
* @desc 柯里化
*/
function checkAge(mini){
return function(age){
return age >= mini;
}
}
const p1 = checkAge(18)(20)
console.log(p1)
//简写
const p1 = mini => age => age >= mini;
console.log(p1(18)(20));
可以借助lodash库提供的Curry,来实现柯里化函数
/**
* 柯里化案例
*/
const _ = require("lodash");
// 调用柯里化函数
const serchTest = _.curry((reg, str) => {
// return reg.test(str);
return str.match(reg);
});
const haveSpace = serchTest(/\s+/g);
// const saveLokersChinese = serchTest(/^(?:[\u4e00-\u9fa5·]{2,16})$/)
// console.log(saveLokersChinese('@#!@3'))
// const saveLokersEmail = serchTest(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
// console.log(saveLokersEmail('a183123123123@163.com'))
// 过滤数组中空白的元素
const filter = _.curry((func, array) => {
return array.filter(func);
});
const result = filter((item) => {
return item.match(/\s+/g);
});
console.log(result(["hello word", "jack rows", "123 44523", ""]));
柯里化实现原理是怎样的?
关键点:需要注意实参与形参之间长度的比较,当实参大于形参,即执行回调函数返回结果;当实参小于形参,立即返回一个已经缓存参数的函数,并等待接收剩余的参数
// lodash的curry
const _ = require("lodash");
function getSum(a, b, c, d) {
return a + b + c + d;
}
const sum = _.curry(getSum);
console.log(sum(1, 2, 3, 4));
console.log(sum(1)(2)(3, 4));
console.log(sum(1, 2)(3, 4));
console.log(sum(1, 2, 3)(4));
// 自定义的curry函数
/**
*
* @param {function} func 要执行的函数
* @return {any} func-value 返回func执行的结果
*/
function curry(func) {
return function curryFn(...args) {
// 当实参<形参时,返回一个函数,并等待接受剩余参数
if (args.length < func.length) {
return function () {
// 合并每次调用函数传递的参数
return curryFn(...[...args, ...Array.from(arguments)]);
};
}
// 当实参>=形参时,调用传递的构造函数;
return func(...args);
};
}
总结:
- 柯里化可以让我们通过传递较少的参数得到一个已经记住固定参数的新函数
- 这个新函数能够对参数进行缓存
- 让函数变得更灵活,让函数进行细腻化
- 能够将多元函数转换成一元函数,并且可以组合成功能更加强大的组合函数