浅析JavaScript 函数柯里化
柯里化(Currying)是把接收多个参数的原函数变换成接受一个单一参数(原来函数的第一个参数的函数)并返回一个新的函数,新的函数能够接受余下的参数,并返回和原函数相同的结果。
ES6的方式实现柯里化的通用
functioncurrying(fn,...rest1){ returnfunction(...rest2){ //这里用apply是为把数组形式的参数直接传入原函数null是因为不需要改变this returnfn.apply(null,rest1.concat(rest2)); } }
将一个sayHello函数柯里化
functionsayHello(name,age,fruit){ console.log(`我叫${name},我${age}岁了,我喜欢吃${fruit}`); } //传入第一个参数 letcurryingShowMsg=currying(sayHello,'小明'); //执行传入剩余参数 curryingShowMsg(22,'芒果');
反柯里化和柯里化刚好相反。为了让方法使用场景更广,使用反柯里化,可以把原生方法借出来,让任何对象拥有原生对象的方法。
二者的区别
//柯里化 //function(arg1,arg2)=>function(arg1)(arg2); //function(arg1,arg2,...,argn)=>function(arg1)(arg2)(...)(argn) //反柯里化 //obj.func(arg1,arg2)=>func(obj,arg1,arg2)
ES6实现一个反柯里化
functionunCurrying(fn){ //tar是我们借给的对象以前需要xxx.fn(xx)现在就可以fn(xxx,xx) returnfunction(tar,...argu){ returnfn.apply(tar,argu); } } //比如我们想把Array.prototype.push方法从原生借出来 letpush=unCurrying(Array.prototype.push); //arrguments是我们借给的对象 push(arguments,4);
函数柯里化的高阶实现,上面的函数只实现一层简单的柯里化如果实现完全的柯里化func(xx)(xx)(xx)(xx)的话,我们要反复嵌套我们的柯里化函数,这里我们实现一个更高阶的柯里化通用方法。
functioncurryingHelper(fn,len){ //这里先说个基本知识点fn.length返回的是这个方法需要传入的参数个数 //这里第一次运行时通过fn.length后面递归都是用的传入的lenlen为剩余的参数个数 constlength=len||fn.length; returnfunction(...rest){ //判断这次传入的参数是否大于等于剩下的参数如果不是递归返回下一个方法继续传参 returnrest.length>=length ?fn.apply(this,rest) :curryingHelper(currying.apply(this,[fn].concat(rest)),length-rest.length) } } //还是刚才的sayHello函数 letbetterShowMsg=curryingHelper(sayHello); //自动控制传参层数 betterShowMsg('zyx')(22)('葡萄'); betterShowMsg('zyx',22)('葡萄');
柯里化的三种用法
1参数的复用
functionSay(name,some){ console.log(name+'说'+some); } //如果我们只想让zyx说一些东西 letzyxSay=currying(Say,'zyx'); zyxSay('1111');//zyx说1111
2提高适用性
//通用函数解决了兼容性的问题,但是同时在不同场景下,我们可能同一种规则需要反复使用 //这就可能会造成代码的重复性比如 functionsquare(i){returni*i}//平方 functiondubble(i){returni*2}//双倍 functionmap(handler,list){ //handle是操作的规则list是操作的arrguments returnlist.map(handler) } map(square,[1,2,3]);//数组每一项平方 map(dubble,[1,2,3]);//数组每一项加倍 //这就是通用性我可以用同一个函数做很多不同的操作 //但是如果我们需要大量做平方操作每次我们都需要传入方法再传入数组就造成的代码浪费 //这时我们通过柯里化提高实用性 letmapSQ=currying(map,square);//直接定义出来的新的平凡操作函数 mapSQ([1,2,3]);//以后就不用传入操作方法了
3延迟执行
letadd=function(...rest){ //定义一个闭包保存_args const_args=[]; returnfunctioncb(...rest){ if(rest.length==0){ //如果不穿参数了也就是add()说明我们需要最后执行函数了 letres=0; //累加 console.log(_args); for(letdataof_args){ res+=data; } returnres; }else{ _args.push(...rest); //为了锁住args闭包 return_args; } } }() add(1); add(2); leta=add(); console.log(a);//3
以上就是浅析JavaScript函数柯里化的详细内容,更多关于JavaScript函数柯里化的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。