JavaScript函数组合_柯里化与管道操作符

柯里化将多参函数转化为单参函数链,提升函数灵活性;函数组合通过compose从右到左串联函数,管道操作符模拟从左到右数据流,增强代码可读性与模块化。

函数组合、柯里化和管道操作符是 JavaScript 中实现函数式编程的重要技术。它们让代码更模块化、可读性更强,也更容易测试和复用。虽然目前原生管道操作符还在提案阶段,但通过函数模拟可以提前体验其优势。下面分别讲解这些概念及其实际应用方式。

柯里化:把多参数函数拆成单参数函数链

柯里化(Currying)是指将一个接受多个参数的函数转换为一系列使用单个参数的函数。每次调用返回一个新的函数,直到所有参数都被传入为止。

例如,一个加法函数:

function add(a, b, c) {
  return a + b + c;
}

柯里化后变成:

function curryAdd(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}

curryAdd(1)(2)(3); // 6

也可以写一个通用的柯里化函数:

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function (...nextArgs) {
        return curried.apply(this, args.concat(nextArgs));
      };
    }
  };
}

这样就能对任意函数进行柯里化:

const curriedAdd = curry(function(a, b, c) {
  return a + b + c;
});

curriedAdd(1, 2, 3); // 6
curriedAdd(1)(2, 3); // 6
curriedAdd(1)(2)(3); // 6

函数组合:将多个函数串联成新函数

函数组合(Function Composition)是指将多个函数连接起来,前一个函数的输出作为下一个函数的输入。常见的组合方式是从右到左执行(数学中的 f ∘ g)。

实现一个组合函数 compose

function compose(...fns) {
  return function(value) {
    return fns.reduceRight((acc, fn) => fn(acc), value);
  };
}

例如,我们有两个简单函数:

const toUpper = str => str.toUpperCase();
const exclaim = str => str + '!';
const sayHello = name => `hello ${name}`;

const greet = compose(exclaim, toUpper, sayHello);
greet('john'); // "HELLO JOHN!"

执行顺序是:sayHello → toUpper → exclaim

管道操作符:从左到右的数据流处理

管道(Pipeline)与组合相反,它是从左到右执行函数链。虽然 JavaScript 原生的管道操作符(|>)还处于提案阶段,但我们可以用函数模拟其行为。

实现一个 pipe 函数:

function pipe(...fns) {
  return function(value) {
    return fns.reduce((acc, fn) => fn(acc), value);
  };
}

同样的例子,使用 pipe 写出来更符合阅读习惯:

const greet = pipe(
  sayHello,
  toUpper,
  exclaim
);

greet('john'); // "HELLO JOHN!"

数据流动方向清晰:原始值 → 经过每个函数依次处理 → 最终结果。

如果未来原生支持管道操作符,代码可能长这样:

'john'
  |> sayHello
  |> toUpper
  |> exclaim
  |> console.log; // 输出: HELLO JOHN!

这种写法避免了深层嵌套,提升了可读性。

基本上就这些。柯里化提升函数灵活性,组合和管道让逻辑流程更清晰。结合使用,能让 JavaScript 代码更简洁、更具表达力。不复杂但容易忽略。