前端函数柯里化

什么是柯里化

柯里化是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下参数的新函数的技术。

比如说,sum(2, 3)可以转换成sum(2)(3)。

柯里化有什么用

柯里化的好处在于,调用函数的时候,如果某一个参数在每次调用中都相同,可以避免重复传入这个参数。

举个栗子

判断n个用户是否是当前用户,假设当前用户为user,要比较的为user1user2,… ,usern

柯里化前
function isSameUser(ua,ub){
	... 
	return ua == ub;
}
//调用n次:
let res1 = isSameUser(user,user1);
let res2 = isSameUser(user,user2);
let res3 = isSameUser(user,user3);
let res4 = isSameUser(user,user4);
...
let resn = isSameUser(user,usern);

以上例子中,每次调用都需要传入user这个对象。

使用柯里化优化
function isSameUser(ua,ub){
	... 
	return ua == ub;
}
function curry(fn){
...
//return 处理后的fn,并固化参数user
return newFn;
}
var isUser = curry(isSameUser)(user);
//调用n次:
let res1 = isUser(user1);
let res2 = isUser(user2);
let res3 = isUser(user3);
let res4 = isUser(user4);
...
let resn = isUser(usern);
再比如
function simpleURL(protocol, domain, path) {
    return protocol + "://" + domain + "/" + path;
}

这个函数是将三个参数生成一个完成的url.调用如下:

var myurl = simpleURL('http', 'mysite', 'home.html');
var myurl2 = simpleURL('http', 'mysite', 'aboutme.html');

很明显,每次调用时前两个参数保持不变,但每次调用都需要传递。所以可以对其优化,仅传递最后一个变化的参数。
如果将函数改成如下:

function simpleURL(path) {
   return "http://mysite/" + path;
}

如果这个库函数有被其它人使用呢,这种情况下基本上是不允许直接改库函数的。并且如果后期还需要处理https的请求呢。难道再把第一个参数加回去?这样别人若使用了该库函数也要修改调用代码。
针对这种情况,使用柯里化函数可以完美解决。

// 避免每次调用重复传参,此处使用lodash.curry
let myURL1 = _.curry(simpleURL)('https', 'mysite');
let res1 = myURL1('home.html');    //

console.log(res1);//https://mysite/home.html

let myURL2 = _.curry(simpleURL)('http', 'mysite');
let res2 = myURL2('aboutme.html');    //

console.log(res2);//http://mysite/aboutme.html

关于实现

以下提供一个简单的手动实现

function _currying(fn, length) {
    return function (...args) {
        if (args.length >= length) {
            return fn(...args)
        }
        return _currying(fn.bind(null, ...args), length - args.length)
    }
}

function add(...args) {
    return args.reduce((a, b) => a + b)
}

add = _currying(add, 7)
console.log(add(1)(2)(3)(4)(5)(6)(7));

柯里化这个概念以及实现本身都比较难懂,平时写代码大多数情况都选择了其它简单的方式实现了。在get到这个技能后,我认为以后可以在项目中适当使用这个方法,尽量减少重复代码。目前只研究了这么些,至于其它的好处和使用场景后期有机会再更新。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值