You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functioncompose(){letargs=arguments;letstart=args.length-1;letresult;leti;returnfunction(){result=args[start].apply(this,arguments);i=start;while(i--){result=args[i].call(this,result);// result = }returnresult;}}compose(greeting)('aa','bb');// "HELLO, aa bb"
functionpipe(){letargs=arguments;letlength=args-1;letresult;letstart=0;returnfunction(){result=args[start].apply(this,arguments);while(start++&&start<=length){result=args[start].call(this,result);}returnresult;}}pipe(greeting,toUpperCase)('cc','ff');// "HELLO, cc ff"
组合 compose
compose()
会把你需要函数结合在一起,像一根管道一样,函数就是这跟管道的节点。你只需要从管道的开始端注入数据,管道会把你的数据处理成你想要的数据然后返回给你。compose()
函数的作用就是组合函数的,将函数串联起来执行,将多个函数组合起来,一个函数的输出结果是另一个函数的输入参数,一旦第一个函数开始执行,就会像多米诺骨牌一样推导执行了。类似于,数学中的复合函数。函数 f 和 g 的组合可以被定义为 f(g(x)),从内到外(从右到左)求值。
1. 特点
compose()
组合函数的参数是函数,返回的也是一个函数;compose()
函数可以接受任意的参数,所有的参数都是函数,且执行方向是自右向左的,初始函数一定放到参数的最右面;2. 举例说明
比如有这样的需求,要输入一个名字,这个名字有由
firstName,lastName
组合而成。如输入 jack,smith 我们就要打印出来,‘HELLO,JACK SMITH’ 。我们考虑用函数组合的方法来解决这个问题,需要两个函数
greeting()
,toUpper()
.使用组合函数,其执行过程是:初始函数为
greeting()
,执行结果作为参数传递给toUpper()
,再执行toUpper()
,得出最后的结果。使用组合函数有一个好处就是,如果我需要对这个结果再加一个处理函数,
trim
()去除这个字符串中的空格。不需要修改 fn, 只需要再调用一次 compose() 函数即可。(拿上次运行的结果来作为本次处理函数的参数,所以只需要将上次的结果函数作为初始函数即可)这里
compose(trimR, fn)
相当于compose(trimR, compose(toUpperCase, greeting))
。利用 compose() 将两个函数组合成一个函数,让代码从右向左运行,而不是由内而外运行,可读性大大提升。这便是函数组合。
但是现在的 compose 函数也只是能支持两个参数,如果有更多的步骤呢?我们岂不是要这样做:
为什么我们不写一个帅气的 compose 函数支持传入多个函数呢?这样就变成了:
3. 好处
先定义做什么,然后在传入数据,就可以得到想要的结果。
4. 实现
思路: 先把传入的函数都缓存起来,然后在传入数据的时候,再挨个的使用apply执行函数, 上一个函数的输出数据,作为下一个函数的输入数据。
compose遵循的是从右向左运行,而不是由内而外运行。也就是说compose是从最后一个函数开始执行。
5. 结合柯里化和组合 Curry + Compose
我们知道,
compose()
组合函数除了初始函数,仅当函数接收一个参数时,才能将函数组合,那多参的函数该如何组合呢?咦...柯里化和偏函数不就是用来分割参数的嘛?首先看个概念:pointfree 指的是函数无须提及将要操作的数据是什么样的。
再看一个复杂的需求:
可以看到,利用柯里化(curry)和函数组合 (compose) 非常有助于实现 pointfree。
那么使用 pointfree 模式究竟有什么好处呢?
管道 pipe
compose()
函数数据流的运行机制,是从右至左,因为最右侧的函数首先执行,将数据传递给下一个函数,以此类推,最左侧的函数最后执行。但也有另外一种方式:从左至右执行,最左侧的函数最先执行,最右侧的函数最后执行。类似于Unix下的 ‘|’ 操作,Unix命令的数据流是从左至右的。我们将这种机制叫做管道 pipe ,他与 compose 所做的事情相同,只不过改变了数据流的方向。
实现:
总结
组合像一系列管道那样把不同的函数联系在一起,数据就可以也必须在其中流动。组合让我们的代码简单而富有可读性。
Reference
JavaScript函数式编程
JavaScript专题之函数组合
The text was updated successfully, but these errors were encountered: