js之函数柯里化

函数柯里化是js函数式编程的一项重要应用,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。假设我们要计算一个表达式如下

         function add(a,b,c){
             return a+b+c;
         }
         add(1,2,3);//直接调用输出
         add(1)(2)(3);//参数分开调用输出

第一种是我们常见的,第二种参数分开调用不常见,但我们也能实现他 如下

      function add(a){
             return function(b){
                 return function(c){
                     return a + b + c;
                 }
             }
         }

显然 ,这样的写法很受参数个数的限制,比较不现实,那么我们需要一个通用函数来实现以上函数功能,这就是基础版的函数柯里化

          var curry = function(func){
             var args = [].slice.call(arguments,1); // 首先我们对通用函数截取参数
             return function(){
                 var newArgs = args.concat([].slice.call(arguments)); //将每次添加的函数连接起来
                 return func.apply(this,newArgs); //将此函数的数组赋给目标函数 并传入参数
             }
         }
         function sub(a,b){
             return a-b;
         }
         var subcurry = curry(sub,5);

         console.log(subcurry(3));

此函数能实现传入不同函数,即在curry(sub,5,3)直接传入参数,或者向上面一样再次传参,或许细心的人已经看出来了,这不就是上面第二种写法,这的确是这样的,因为他还不能实现subcurry(5)(3);这样的操作,别急,这只是让你熟悉下柯里化的过程,其实柯里化的核心就是在自我简化,当一个函数需要多个参数时,我们可以层层简化,使得我们的参数变换更随意,虽然一定程度上让代码更复杂了。接下来是改进版

function add(a,b){
             return a + b;
         }
         var currys = function(fn,args){
             var length = fn.length; //计算期望函数的参数长度
            args =args || []; //利用闭包特性保存参数
             return function(){
                 newArgs = [].slice.call(arguments); //将自身函数参数赋给新参数

                 [].push.apply(newArgs,args); //将上回保留的参数push进新的数组

                 if(newArgs.length<length){ //判断当前函数的参数是否与期望函数参数一致
                     return curry.call(this,fn,newArgs); //如果不够,递归调用
                 }else{

                     return fn.apply(this,newArgs); // 如果够,就执行期望函数
                 }
             }
         }
         var addcurry = currys(add);
         console.log(addcurry(1)(2));

这里首先用addcurry绑定add函数,然后在进行传参,每执行一次就传入一个参数,直到所有参数传入完成就会执行期望函数 add。

当然,这只是一个改进版的通用柯里,他限制与特定的参数,如果想要不限定参数,则需要进一步修改,这里就不做出过多解释,可以自己去百度,因为这里需要自己去多琢磨才能搞懂,而不是看一篇博客就能搞懂,这里给出一到面试题

实现一个add方法,使得计算结果能满足一下表达式

add(1)(2)(3 ) =6;

add(1,2,3)(4)=10;

add(1)(2)(3)(4)(5) =15;

这里由于要将进行参数个数不确定计算,这里就要在函数内部重写toSting方法或者valueOf方法(这两个方法都是Object原型上的,一个是返回一个对象的值,默认是本身,一个是返回对象字符串)

原文地址:https://www.cnblogs.com/maoxiaodun/p/10035861.html

时间: 2024-10-11 05:23:30

js之函数柯里化的相关文章

【转载】JS中bind方法与函数柯里化

原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情况戳这里ECMAScript 5 compatibility table),权威指南上提到在ES3中利用apply模拟该方法的实现(JS权威指南中函数那章), 但无法真实还原该方法, 这也是真bind方法中的有趣特性. (原文这边理解有问题, 这段话的意思如果结合犀牛书上下文的意思, 再结合犀牛书中

【转】详解JS函数柯里化

第一次看到柯里化这个词的时候,还是在看一篇算法相关的博客提到把函数柯里化,那时一看这个词就感觉很高端,实际上当你了解了后才发现其实就是高阶函数的一个特殊用法.果然是不管作用怎么样都要有个高端的名字才有用. 首先看看柯里化到底是什么? 维基百科上说道:柯里化,英语:Currying(果然是满满的英译中的既视感),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 看这个解释有一点抽象,我们就拿被做了无数次示例的add函数,

JS函数柯里化

第一次看到柯里化这个词的时候,还是在看一篇算法相关的博客提到把函数柯里化,那时一看这个词就感觉很高端,实际上当你了解了后才发现其实就是高阶函数的一个特殊用法. 果然是不管作用怎么样都要有个高端的名字才有用. 首先看看柯里化到底是什么? 维基百科上说道:柯里化,英语:Currying(果然是满满的英译中的既视感),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 看这个解释有一点抽象,我们就拿被做了无数次示例的add函数

[转]js函数式变成之函数柯里化

本文转自:https://segmentfault.com/a/1190000003733107 函数柯里化是指参数逐渐求值的过程. 我觉得它是:降低通用性,提高专用性. 通常,柯里化是这样的过程,“如果你固定某些参数,你将得到接受余下参数的一个函数”.所以对于有两个变量的函数y^x,如果固定了 y=2,则得到有一个变量的函数 2^x 通用实现 全选复制放进笔记 function currying(fn) { var slice = Array.prototype.slice; var args

js高阶函数应用—函数柯里化和反柯里化

在Lambda演算(一套数理逻辑的形式系统,具体我也没深入研究过)中有个小技巧:假如一个函数只能收一个参数,那么这个函数怎么实现加法呢,因为高阶函数是可以当参数传递和返回值的,所以问题就简化为:写一个只有一个参数的函数,而这个函数返回一个带参数的函数,这样就实现了能写两个参数的函数了(具体参见下边代码)--这就是所谓的柯里化(Currying,以逻辑学家Hsakell Curry命名),也可以理解为一种在处理函数过程中的逻辑思维方式. 1 function add(a, b) { 2 retur

JS中的柯里化(currying)

何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果.因此柯里化的过程是逐步传参,逐步缩小函数的适用范围,逐步求解的过程. 柯里化一个求和函数 按照分步求值,我们看一个简单的例子 var concat3Words = function (a

JavaScript函数柯里化的一些思考

1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函数f1和f是等效的,我们直接令var f1 = f;就行了,完全没有必要包裹那么一层. 但是,下面一段代码就未必能够看得出问题来了: var getServerStuff = function(callback){ return ajaxCall(function(json){ return cal

精读JavaScript模式(六),Memoization模式与函数柯里化的应用

假期就这么结束了!十天假就有三天在路上,真的难受!想想假期除了看了两场电影貌似也没做什么深刻印象的事情.流浪地球,特效还是很赞,不过对于感情的描写还是逃不掉拖沓和尴尬的通病,对于国产科幻还是抱有支持的态度.疯狂的外星人相比读大学期间看的疯狂的赛车,荒诞感还是差了点,也许是我笑点太高...不过整体还是感觉比流浪地球值票价,个人观点吧. 开年来同事说自己小舅子年终奖税后18W,他这两天深受打击,我听完也深受打击,哎. 假期结束也该好好安排下今年的时间了,年底辞职的规划不变,加上未来几年要结婚,想想还

浅谈函数柯里化

关于函数柯里化的定义,我摘抄一段来自百度百科的原话:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术. 这段话听起来可能有一些抽象,但是如果用实际例子来解释可能会帮助我们更好地理解何为函数柯里化.看看下面这个问题,是一道前端面试中常考的题: 如何实现add(2)(3)(4) = 9 当我第一次看到这个题目的时候我就在思考,add(2)后面为什么还能带(3)(4)呢?是不是因为add