0Pricing
JavaScript Academy · 课时

函数组合

将小型函数组合成数据流管道。

函数组合 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。

什么是函数组合

函数组合可以将多个小函数合并为一个函数。组合 f 和 g 会生成一个函数,其中 g 的输出成为 f 的输入。

数学表示为:compose(f, g)(x) = f(g(x))。数据从右向左流动。

两个小函数

函数组合从简单的单一用途函数开始。下面是两个要组合的转换函数。

const double = x => x * 2;
const increment = x => x + 1;

console.log(double(5));
console.log(increment(5));

手动进行组合

最直观的函数组合,就是对一个函数的结果调用另一个函数。请从内向外阅读:先运行 increment,再运行 double。

const double = x => x * 2;
const increment = x => x + 1;

const result = double(increment(5));
console.log(result);

用于两个函数的 compose 函数

将这一模式封装到可复用的 compose 中。它接收 f 和 g,并返回一个先应用 g、再应用 f 的新函数。

const compose = (f, g) => x => f(g(x));

const double = x => x * 2;
const increment = x => x + 1;

const doubleThenAfterIncrement = compose(double, increment);
console.log(doubleThenAfterIncrement(5));

顺序很重要

函数组合不满足交换律。compose(f, g) 与 compose(g, f) 不同,因为右侧函数会先运行。

const compose = (f, g) => x => f(g(x));

const double = x => x * 2;
const increment = x => x + 1;

console.log(compose(double, increment)(5));
console.log(compose(increment, double)(5));

从右向左阅读

在 compose(a, b, c)(x) 中,调用过程相当于 a(b(c(x)))。最右侧的函数会先处理输入。请牢记这个方向,以免引入错误。

const compose = (f, g) => x => f(g(x));

const shout = s => s.toUpperCase();
const exclaim = s => s + '!';

const loud = compose(shout, exclaim);
console.log(loud('hello'));

组合字符串转换

函数组合非常适合文本管道:先执行 trim,再转换为小写,然后使用 replace 替换空格,每一步都是一个小型函数。

const compose = (f, g) => x => f(g(x));

const trim = s => s.trim();
const lower = s => s.toLowerCase();

const clean = compose(lower, trim);
console.log(clean('   HELLO World  '));

组合数字运算

串联数学运算是一个经典示例。每个函数都可以单独进行简单测试。

const compose = (f, g) => x => f(g(x));

const square = x => x * x;
const negate = x => -x;

const negativeSquare = compose(negate, square);
console.log(negativeSquare(4));

为什么使用 compose

函数组合让每个函数各司其职并且可以复用,同时消除了嵌套调用的杂乱。您不必让 f(g(h(x))) 散落在代码中,而是可以一次构建一个命名管道,然后重复使用。

const compose = (f, g) => x => f(g(x));

const toCents = d => Math.round(d * 100);
const addLabel = c => c + ' cents';

const priceLabel = compose(addLabel, toCents);
console.log(priceLabel(2.5));

函数组合与柯里化结合

柯里化函数非常适合进行组合,因为每个函数都会产生一个单参数函数,而这正是函数组合所需要的形式。

const compose = (f, g) => x => f(g(x));
const add = a => b => a + b;
const multiply = a => b => a * b;

const addThenDouble = compose(multiply(2), add(3));
console.log(addThenDouble(5));

迈向多个函数

到目前为止,compose 只能处理两个函数。实际的函数组合可以支持任意数量的函数。在下一课中,您将使用 reduce 构建通用的 compose,以及它从左到右执行的对应形式 pipe。

const compose = (f, g) => x => f(g(x));
const a = x => x + 1;
const b = x => x * 2;
const c = x => x - 3;

const combined = compose(a, compose(b, c));
console.log(combined(10));

快速检查

如果 compose = (f, g) => x => f(g(x)),并且 double 将数字乘以 2、increment 将数字加 1,那么 compose(double, increment)(5) 返回什么?

回顾:函数组合

您已经学会组合函数:

  • compose(f, g)(x) 等于 f(g(x)),按从右向左的顺序求值。
  • 顺序很重要:函数组合不满足交换律。
  • 函数组合让函数保持小巧、有名称且可复用。
  • 柯里化函数可以清晰地进行组合。接下来您将把它推广到任意数量的函数。

常见问题解答

「函数组合」课时是免费的吗?

是的 — 「函数组合」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。

「函数组合」这节课中我会学到什么?

将小型函数组合成数据流管道。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 JavaScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「函数组合」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 JavaScript Academy 课中编写并运行代码吗?

能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 偏应用
  2. 函数柯里化
  3. 函数组合
  4. 构建 pipe 和 compose
← 返回 JavaScript Academy