函数柯里化
什么是柯里化
简单来说,一般函数中如果需要传参,则必须所有参数都传入之后才能开始执行该函数。而在函数柯里化之后,可以将参数分开传入,函数依然可执行。可以理解为延迟接受参数。
例子
// 一般函数
function fn1 (a, b) {
return a + b ;
}
fn1(1, 2); // 输出结果为 3
// 柯里化函数
function fn2 (a) {
return function (b) {
return a + b;
};
};
fn2(1)(2) // 输出结果为 3
原理
在JS中的函数柯里化是利用的是闭包的原理,通过闭包返回一个函数,该函数中的参数以及变量将被缓存,便于遍历调用。
实现
简易版
// 箭头函数版
const people = name => age => sex => console.log('名字:'name, '年龄:'age, '性别:'sex);
// 普通函数版
function people(name) {
return function age(age) {
return function sex(sex) {
console.log('名字:' + name, '年龄:' + age, '性别:' + sex);
};
};
}
people('张三')(18)('男') // 输出结果为 "名字:张三 年龄:18 性别:男"
在这种情况下只能单个参数去传
改进版
const people = (name, age, sex) => console.log('名字:' + name, '年龄:' + age, '性别:' + sex);
const toCurry = (fn, ags) =>
fn.length <= ags.length ? // fn.length 为参数的长度
fn(...arguments) : toCurry(fn, ags, ...arguments )
const newFn = toCurry(people);
newFn('张三',18,'男');
newFn('张三')('18,'男'');
newFn('张三')(18)('男');
newFn()()()()()('张三')(18)('男');
// 以上输出结果皆为 "名字:张三 年龄:18 性别:男"
实际用途
函数在柯里化之后,可先调用函数,传入固定的参数,减少之后的每次调用需要重复调参
// 柯里化函数写法
function add(x) {
return function(y) {
return x + y;
};
}
// 调用柯里化函数
const add5 = add(5);
console.log(add5(3)); // 8
console.log(add5(7)); // 12
实际例子
// 请求接口,接口地址一样,但是配置config信息参数不一样,每次都需要重复传入接口地址参数'www.abc.com'
request1 ('www.abc.com',{'id': '1','color': 'red'});
request1 ('www.abc.com',{'id': '2','color': 'blue'});
// 柯里化之后,只需要传入第二个参数即可
const request2 = toCurryRequest(request('www.abc.com'));
console.log(request2({'id': '1','color': 'red'}));
console.log(request2({'id': '2','color': 'blue'}));
优劣
好处
- 参数复用
- 增加函数的灵活性
坏处
- 性能消耗增加,存在闭包,使用额外内存存储数据
- 可能会增加代码复杂性