JavaScript 函数增强之高阶函数
2025-04-12 03:10:18 1.3k 字
This post is also available in English and alternative languages.
我平时用 Java 开发,发现 JavaScript 的高阶函数(Higher-Order Functions)和 Java 8 的「行为参数化(Behavior parameterization)」有许多相似之处。这篇文章就来探讨高阶函数的概念及其应用。
1. 高阶函数是啥?
高阶函数就是一个”会玩函数的函数”。它有两种”玩法”:
- 接收函数:把其他函数作为参数传入
- 返回函数:返回一个新函数作为结果
普通函数就像一个老老实实的工人,只会干一件事。高阶函数则像个”工头”,要么指挥别的工人干活,要么培训一个新工人出来。
想象你在饭店点菜:
- 普通函数是”厨师”,你说炒个青菜,他就炒青菜。
- 高阶函数是”老板”,你告诉他”怎么炒”(比如加辣、不加盐),他再指挥厨师按你的想法干。
2. 与Java 8「行为参数化」对比
在 Java 8 中,我们通常使用 Lambda 表达式和流式 API 来实现行为参数化:
1 | import java.util.Arrays; |
JavaScript 的高阶函数实现类似功能:
1 | const numbers = [1, 2, 3, 4, 5]; |
- 相同点:
- 都将”行为”作为参数传递(Java 使用 Lambda,JavaScript 使用函数)
- 都避免了硬编码逻辑,提高了代码复用性和灵活性
- 都遵循函数式编程的思想
- 不同点:
- Java 需要通过函数式接口和类型系统来实现,语法相对复杂一些
- JavaScript 作为函数式语言,函数是一等公民,可以直接传递函数
本质上,高阶函数和「行为参数化」都是函数式编程思想的体现:将”怎么做”参数化,使代码更加灵活和可复用。
3. 高阶函数的两种类型
3.1. 接收函数作为参数
这种高阶函数将其他函数作为参数,让它们执行特定任务:
1 | function filterArray(arr, predicate) { // predicate 是一个函数(行为) |
filterArray
是高阶函数,它不直接实现筛选逻辑,而是通过 predicate
函数来决定”筛选什么”。这样一个函数就能应对各种筛选需求。
3.2. 返回函数作为结果
这种高阶函数返回一个新函数,像个”工厂”,可以生产定制化的函数:
1 | function createGreeter(greeting) { |
createGreeter
是个”函数工厂”,你给它一个问候词,它就生产一个专用的问候函数。
4. 高阶函数的实际应用
4.1. 自定义排序
1 | const students = [ |
4.2. 函数组合
1 | // 函数组合:将多个函数组合成一个函数 |
5. 小结
使用高阶函数有很多好处:
- 代码简洁:减少重复代码,提高可读性
- 灵活性:同一个高阶函数可以应对不同场景
- 可测试性:更容易单元测试
- 可组合性:可以组合多个小函数实现复杂功能
- 抽象层次:提高代码的抽象层次,更加专注于”做什么”而非”怎么做”
对比一下不使用高阶函数和使用高阶函数的代码差异:
不适用高阶函数
1
2
3
4
5
6
7
8const numbers = [1, 2, 3, 4, 5];
let evens = [];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] % 2 === 0) {
evens.push(numbers[i]);
}
}
console.log(evens); // [2, 4]使用高阶函数:
1
2
3const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]
高阶函数版本不仅代码更简洁,而且更加声明式,直接表达了”我想要筛选偶数”的意图,而不是陷入具体的实现细节。
高阶函数是”会玩函数的函数”——它能接收函数作为参数或返回函数作为结果。与Java 8的「行为参数化」类似,高阶函数将”怎么做”参数化,使代码更加灵活和可复用。