天天看点

JavaScript函数编程-Ramdajs

JavaScript函数编程-Ramdajs

在javascript语言世界,函数是第一等公民。javascript函数是继承自function的对象,函数能作另一个函数的参数或者返回值使用,这便形成了我们常说的高阶函数(或称函数对象)。这就构成函数编程的第一要素。在javascript世界中有很多的函数式编程库能辅助我们的javascript函数式体验,在它们之中最为成功的要数underscore或lodash。

如下lodash实例代码:

函数式思想展现的是一种纯粹的数学思维。函数并不代表任何物质(对象,相对于面向对象思想而言),而它仅仅代表一种针对数据的转换行为。一个函数可以是原子的算法子(函数),也可以是多个原子算法子组成的组合算法子。它们是对行为的最高抽象,具有非凡的抽象能力和表现力。

虽然underscore或lodash也提供了.compose(或.flowright)函数来实现函数组合的能力,但ramdajs具有更强的组合力。

在计算机科学中,柯里化(currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 christopher strachey 以逻辑学家 haskell curry 命名的,尽管它是 moses schnfinkel 和 gottlob frege 发明的。

在理论计算机科学中,柯里化提供了在简单的理论模型中比如只接受一个单一参数的lambda 演算中研究带有多个参数的函数的方式。

ramdajs利用这一技术,默认所有api函数都支持自动柯里化。这为它提供了可以将另一个函数组合的先决条件。如常用的map操作需要接受两个参数,在ramdajs中可以如下两种方式实现:

如果我们传入2个完备的参数,则r.map函数将会直接执行。否则,它将返回另一个函数,等待参数完备时才执行。

在underscore和lodash这类库中,都要求首先传入数据,然后才是转换函数。而在ramdajs却是颠覆性的改变。在它的规约中数据参数是最后一个参数,而转换函数和配置参数则优于数据参数,排在前面。

将转换函数放置在前面,再加上函数的自动柯里化,就可以在不触及数据的情况下,将一个函数算法子包装进另一个算法子中,实现两个独立转换功能的组合。

假设,我们拥有如下两个基础算法子:

r.multiply(a, b):实现 a *b; 2:r.map(func, data):实现集合 a –> b的map。

因为可以自动柯里化,所以有

所以上面对数组map的例子则可以转为如下形式:

r.map(r.multiply(2))的返回值也是一个函数,它是一个组合转换函数。它组合了map和multiply行为。它利用r.map组合封装了r.multiply(2)返回的柯里化函数,它等待map函数传入对应的被乘数。

有了上面的两个条件,再加上ramdajs为我们提供的r.compose方法,我们就能很容易的实现更多算法子的组合。r.compose是从右向左执行的数据流向。

用ramdajs的组合来实现开篇lodash一样的用户名拼接的例子,则我们可以分为2个算法子的组合:

r.pluck(prop):选择对象固定属性;

r.join(data):对数组的字符串拼接。

则代码如下所示:

这里的函数式组合可表示为下图:

JavaScript函数编程-Ramdajs

如果我们希望join用户的年龄,则如下:

假设我们希望输出的不是用户年龄,而是用户生日,则我们可以轻易组合上一个减法的算法子:

r.subtract(a, b):实现 a – b 数学算法。

则代码如下:

再如,我们希望获取最年轻的用户:

lodash实现:

ramdajs则,可以组合获取第一个元素的r.head算法子和排序算法子r.sortby:

比如我们希望获取年长的用户,则只需再组合一个反序排列的算法子r.reverse:

继续阅读