高阶函数与函数组合
最初发布于@ CatStache.io
你有没有想过高阶函数 (HOF) 是什么?它能如何在你编写代码时提供帮助?不用再犹豫了!
在这篇文章中,我将展示一些 HOF 在日常 JavaScript 中的使用示例,如何编写自己的 HOF,以及作为奖励的关于组合函数的小部分。
什么是高阶函数(HOF)?
简而言之,高阶函数是执行以下一项或两项操作的函数:
- 将一个或多个函数作为参数。
- 返回一个函数。
下面是您可以编写的使用 HOF 的一些代码的简单示例:
const nums = [1,2,3,4,5,6];
const isEven = number => {
return number % 2 === 0;
};
// evens will be an array with elements [2,4,6]
const evens = nums.filter(isEven);
这里我们使用数组过滤方法,该方法将一个函数作为参数,该函数接受单个参数(数组的一个元素),并返回true
是否应保留该元素以及false
是否应丢弃该元素。
您可能还会发现上面的代码是用匿名函数编写的,它看起来像这样:
const nums = [1,2,3,4,5,6];
const evens = nums.filter(n => n % 2 === 0);
虽然上面的代码演示了过滤器,但你会发现许多将函数作为参数传递给其他数组方法的例子,例如 map、reduce、every 等。这种模式将开始在 JavaScript 代码的各个地方出现 - 你可能已经在使用这个概念,只是不知道它的名字!
扩展 isEven 函数
HOF 的一个优点是,它允许我们编写一些代码,以新颖有趣的方式组合函数。想象一下,上面的代码越来越长,我们还需要能够获取一个奇数列表。我们可以很容易地编写一个isOdd
与 非常相似的函数isEven
,但我们也知道,在这种情况下,它与isEven完全相反。不幸的是,我们不能只写const evens = nums.filter(!isEven)
,即使这基本上是我们想要的。我们可以做的是创建一个名为 的新函数,not
它接受一个函数作为参数,并返回一个将传入函数的值取反的新函数:
const nums = [1,2,3,4,5,6];
const isEven = n => {
return n % 2 === 0;
};
const not = f => {
return x => !f(x);
};
const isOdd = not(isEven);
// odds will be an array with elements [1,3,5]
const odds = nums.filter(isOdd);
太棒了!我们的函数not
满足了 HOF 的两个要求,因为它接受一个函数作为参数,并返回一个新函数作为结果,我们将其绑定到isOdd
。你可以利用 HOF,通过复用小函数的逻辑来构建更复杂的功能,太棒了!
使用函数组合来简化代码
虽然函数组合与 HOF 主题并非严格相关,但你可能希望使用它来编写简洁的函数式代码。我建议你使用诸如lodash/fp
或 之类的库来获取它们的 compose 函数。这是 ramdajs 的compose 函数ramdajs
的文档。
not
在以 HOF 的形式编写时,我确实在我的示例中添加了一些额外的机制,即接受一个函数并返回一个函数。最简单的独立版本not
可以写成const not = v => !v;
。也就是说,它只接受一个布尔值并返回其逆。not
如果我使用 ,我也可以这样编写函数compose
。以下是这样做的示例:
import R from 'ramda';
const nums = [1,2,3,4,5,6];
const isEven = n => n % 2 === 0;
const not = v => !v;
const isOdd = R.compose(not, isEven);
const odds = nums.filter(isOdd);
在我看来,这是迄今为止最简洁的代码版本,最棒的是它R.compose
包含了尽可能多的函数!这让我们可以开始编写可组合、易于测试和推理的函数式代码!
结论
最后,高阶函数在 JavaScript 中非常流行——如果你在学习过程中偶然发现了它,那么你可能已经在不知不觉中运用了这个概念!如果你最终倾向于编写更具函数式风格的 JavaScript,那么高阶函数将是你大量使用的概念,并且当与组合结合使用时,代码将变得易于测试、组合和推理!
文章来源:https://dev.to/bamartindev/higher-order-functions-function-composition-c7p