函数柯里化(基础)

配图.png

简介

与函数绑定紧密相关的主题是函数柯里化(function currying),它用于创建已经设置好了一个或多个参数的函数。函数柯里化的基本方法和函数绑定是一样的:使用一个闭包返回一个函数。两者的区别在于,当函数被调用时,返回的函数还需要设置一些传入的参数。请看以下例子。

柯里化写法(简单)

function add(num1, num2) {
    return num1 + num2;
}
function curryadd(num3){
    return add(5,num3)
}
curryadd(3);//8;

首先这个其实就是函数柯里化的雏形。不过,我们工作中不可能这么使用。或者有的同学对官方的这个例子不是太懂。那就写一个更为简单的例子

function add2(num1){
    return function(num2){
        return num1+num2;
    }
}
add2(1)(2);//3

相信看这个例子就更为简单,那么又该如何把它改造的更好?因为它使用起来特别麻烦。不过这就是柯里化。那么柯里化又该如何书写,怎么写更好?请继续往下读

柯里化写法(动态)

柯里化的写法,一般分为柯理化函数与功能函数。也就是两个函数。那么对于柯里化函数,它只相当于对功能函数的又一次封装。

//这里是功能方法
function add(num1, num2) {
    return num1 + num2;
}
//这里是柯里化函数
function curry(fn){
    //对内部传递的参数进行保留值。
    var args = [].slice.call(arguments,1); //将add方法除外的其它参数保留下来。
    return function(){
        var innerArgs = [].slice.call(); //将内部的参数放在arr中
        [].push.apply(args,innerArgs); //将外部的数据添加到 args数组中,因为闭包,可以继续访问
        return fn.apply(this,args);//进行运算
    }
}
var curryfn = curry(add,2); //对add方法进行封装.形成新的方法
console.log(curryfn(1));//这个函数是可以传递参数的 这里传进的1就是在函数中通过innerArgs接收的。

改造add方法

以上方法中,其实已经解决了前面的问题,不过这里存在一个问题,就是这里面的参数是固定的,原因是因为定义的add方法,里面参数是固定的.
我们可以改造add方法:其实就是通过for循环将传递的参数全部进行计算即可.

function add(){
    var res = 0;
    for (var i = 0; i < arguments.length; i++) {
        res += arguments[i];
    };
    return res;
}
var currayfn = curray(add,2,3,4);
currayfn(7,8,9);//35
currayfn();//9

可以发现这里已经将参数扩展了很多,效果比以前是好了许多。在这里面我们可以看到在实现currayfn这个方法时,curray(add,2,3,4) 第二个以后的参数 以及调用currayfn()的参数都是可写可不写.极大的方便了我们的工作.

升级柯里化方法

我们可以看一下如果代码写到这里说明我们已经对柯里化或者对我们之前的闭包已经很熟悉了,不过我们的扩展性并没有完全发挥到极致.我们可以尝试以下一种写法.
curray(add,1,2)(3,4)(2)();

function curry(fn){
    //对内部传递的参数进行保留值。
    var args = [].slice.call(arguments,1);
    //将add方法除外的其它参数保留下来。
    var newfn = function(){
        if(arguments.length == 0){
            //没有参数时,对args进行加法运算
            return fn.apply(this,args)
        }else{
            //有参数时,将数据添加到外部数组中
            [].push.apply(args,arguments)
            //将自身这个柯里化函数重新返回可以连续执行.
            return newfn;
        }
    }
    return newfn;
}
//第一种写法
curray(add,1,2)(3,4)(2)();
//第二种写法
var currayadd = curray(add);
currayadd(1)
currayadd(2)
currayadd(3)
currayadd(4)
currayadd(2)
currayadd()//只有在调用函数里面不传参时,才能进行累加

这里面将匿名函数改写成了定义式写法,原因是因为递归.(可以选择匿名函数,返回arguments.callee即可)
递归:
1.每次如果有参数就添加到外部的数组中
2.每次curray后面调用一次就要返回一个新的柯里化函数

讨论一下

1.最后一种写法,里面的参数可以无限多个,而且有个好处就是,它是将所有的数字每次调用都添加到数组中,当最后调用时无参数才执行.curray(add,1,2)(3,4)(2)().
2.如果按照我们最初的写法进行计算效果如:sum(sum(sum(sum(1,2),3),4),2)
a).能够明显的感觉到代码质量比较低,同时函数调用时,需要重复不断的写函数名称.同时,它在调用函数sum(x,y)那么就会执行一次,里面的函数就会进行一次计算.
b).当代码量少的情况下,使用最初的sum会方便很多.当数据量非常大时,我们使用下面的写法无论从代码量,写法,以及性能上方便许多:
3.这里只是加法运算的柯里化,那么柯里化是一种思想,适用性非常广泛,下节课我们可以讨论一下柯里化的适用场景.

总结:

总之柯里化的原理是非常简单的,重点在于应用.后面会继续分享柯里化的更多用法.不过重点就在于开始时它的基本理念,一定要理解,当函数被调用时,返回的函数还需要设置一些传入的参数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容