参数:需要柯里化的函数 返回值:柯里化后的函数 使用:functioncompareSize(a){letb=2returna>b}console.log(compareSize(1));//falseconsole.log(compareSize(2));//falseconsole.log(compareSize(3));//true0柯里化总结柯里化对于函数式JavaScript是一种极其有用的技术。它允许你生成一个简洁、...
函数柯里化Currying|函数式编程
前言一个简单的纯函数:
//比较两个数大小的纯函数functioncompareSize(a,b){returna>b}console.log(compareSize(1,2));//falseconsole.log(compareSize(2,2));//falseconsole.log(compareSize(3,2));//true在上面的纯函数中,我们对两个数值进行了比较,参数b在三次函数的调用中,都是一样的数值2。
既然这样,那我们改写一下吧。
functioncompareSize(a){letb=2returna>b}console.log(compareSize(1));//falseconsole.log(compareSize(2));//falseconsole.log(compareSize(3));//true改写后的代码,参数变成了一个a,虽然结果和上次一样,函数compareSize也还是一个纯函数。
但是内部出现了一个固定的参数b,这样其实变成了hardcode(硬编码)的写法?。是一种固化的代码,代码在内部写死了,修改起来会很麻烦。
让我们再换一种方式试一下:
functioncompareSize(b){returnfunction(a){returna>b}}consthasThanTarget=compareSize(2)console.log(hasThanTarget(1));//falseconsole.log(hasThanTarget(2));//falseconsole.log(hasThanTarget(3));//true最后这种方式其实就是一种函数柯里化的处理方式,所谓"柯里化",就是把一个多参数的函数,转化为单参数函数。
函数柯里化的定义在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
这个技术由克里斯托弗·斯特雷奇以逻辑学家哈斯凯尔·加里命名的,尽管它是MosesSch?nfinkel和戈特洛布·弗雷格发明的?。
函数柯里化的作用参数复用通过柯里化方法,缓存参数到闭包内部参数,然后在函数内部将缓存的参数与传入的参数组合后给函数执行,来实现参数的复用,降低通用性,提高适用性.
?例子:对正则校验的方法,进行Currying.
functioncurryingCheck(reg){returnfunction(txt){returnreg.test(txt);};}//ES6letcurryingCheck=reg=>(txt=>reg.test(txt))使用:
//正则:只能输入数字lethasNumber=curryingCheck(/^\d+$/);console.log(hasNumber("test"));//falseconsole.log(hasNumber(1));//true//正则:手机号校验lethasPhone=curryingCheck(/^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/);console.log(hasPhone("test"));//falseconsole.log(hasPhone(18577331234));//true延迟运行如果调用柯里化函数传入参数是不调用的,会将参数添加到数组中存储,等到没有参数传入的时候进行调用.
?例子:求和运算,进行Currying.
functionadd(){varargs=Array.prototype.slice.call(arguments);var_that=this;returnfunction(){varnewArgs=Array.prototype.slice.call(arguments);vartotal=args.concat(newArgs);if(!arguments.length){varresult=1;for(vari=0;i<total.length;i++){result*=total[i];}returnresult;}else{returnadd.apply(_that,total);}}}使用:
add(1)(2)(3)();//6add(1,2,3)();//6函数柯里化原理及模拟实现原理利用闭包原理在执行可以形成一个不销毁的作用域,然后把需要预先处理的内容都储存在这个不销毁的作用域中,并且返回一个最少参数函数。
模拟实现上面的例子中的柯里化函数不够通用,下面来模拟实现一个(来源)
functioncurry(fn,args){varlength=fn.length;args=args||[];
returnfunction(){var_args=args.slice(0),arg,i;
for(i=0;i<arguments.length;i++){arg=arguments[i];_args.push(arg);}if(_args.length<length){returncurry.call(this,fn,_args);}else{returnfn.apply(this,_args);}};}
使用:```jsvarfn=curry(function(a,b,c){console.log([a,b,c]);});fn("a","b","c");//["a","b","c"]fn("a","b")("c");//["a","b","c"]fn("a")("b")("c");//["a","b","c"]fn("a")("b","c");//["a","b","c"]lodash中使用柯里化函数?推荐工作中使用_.curry(func)
功能:创建一个函数,该函数接受一个或多个func的参数,如果func所需要的参数都被提供,则执行func并返回执行的结果,否则继续返回该函数并等待接受剩余的参数.
参数:需要柯里化的函数
返回值:柯里化后的函数
使用:
functioncompareSize(a){letb=2returna>b}console.log(compareSize(1));//falseconsole.log(compareSize(2));//falseconsole.log(compareSize(3));//true0柯里化总结柯里化对于函数式JavaScript是一种极其有用的技术。
它允许你生成一个简洁、易配置、表现统一的库,而且使用起来上手快、具有可读性。
在你的编码实践中加入柯里化会激励你在全部代码中的部分函数上应用它,这样避免了很多潜在的重复工作,并可以帮助你养成关于函数命名和处理函数参数的好习惯。
参考什么是函数柯里化
函数式编程入门教程
柯里化-WIKI
哈斯凯尔·加里-百度百科
JavaScript专题之函数柯里化
2019前端面试系列——JS高频手写代码题
函数柯里化
JS中的柯里化
掌握JavaScript函数的柯里化
js基础篇之——JavaScript的柯里化函数详解
2024-09-18