函数式编程模式(Functional Programming Patterns)

函数式编程的常见模式和实践。


📚 核心模式

1. 纯函数(Pure Functions)

输入相同,输出始终相同,无副作用:

// ✅ 纯函数
function add(a, b) {
  return a + b;
}
 
// ❌ 非纯函数(有副作用)
let counter = 0;
function increment() {
  counter++; // 修改外部状态
  return counter;
}
 
// ❌ 非纯函数(依赖外部状态)
function getCurrentTime() {
  return new Date(); // 依赖时间
}

2. 函数组合(Function Composition)

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

// 组合函数
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);
const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
 
// 使用
const add1 = x => x + 1;
const multiply2 = x => x * 2;
const add1ThenMultiply2 = pipe(add1, multiply2);
console.log(add1ThenMultiply2(3)); // 8

3. 柯里化(Currying)

将多参数函数转换为单参数函数链:

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 add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6

4. 部分应用(Partial Application)

固定函数的部分参数:

function partial(fn, ...fixedArgs) {
  return function(...remainingArgs) {
    return fn(...fixedArgs, ...remainingArgs);
  };
}
 
const multiply = (a, b) => a * b;
const double = partial(multiply, 2);
console.log(double(5)); // 10

5. 闭包(Closures)

函数可以访问外部作用域的变量:

function createCounter() {
  let count = 0;
  return function() {
    return ++count;
  };
}
 
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

🎯 数据处理模式

1. Map-Reduce 模式

const numbers = [1, 2, 3, 4, 5];
 
// Map: 转换每个元素
const doubled = numbers.map(n => n * 2);
 
// Reduce: 聚合结果
const sum = numbers.reduce((acc, n) => acc + n, 0);

2. 管道模式

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
 
const process = pipe(
  x => x * 2,
  x => x + 1,
  x => x.toString()
);
 
console.log(process(5)); // "11"

3. 链式调用

const numbers = [1, 2, 3, 4, 5];
 
const result = numbers
  .filter(n => n % 2 === 0)
  .map(n => n * 2)
  .reduce((acc, n) => acc + n, 0);
 
console.log(result); // 12

💡 实际应用

1. 数据转换

const users = [
  { name: 'Alice', age: 25, active: true },
  { name: 'Bob', age: 30, active: false }
];
 
// 函数式处理
const activeUserNames = users
  .filter(user => user.active)
  .map(user => user.name.toUpperCase())
  .sort();

2. 事件处理

const handleClick = pipe(
  getEventTarget,
  getDataAttribute,
  parseJSON,
  updateState
);
 
button.addEventListener('click', handleClick);

3. 配置构建

const createConfig = pipe(
  setDefaults,
  applyEnvironment,
  validateConfig
);
 
const config = createConfig(userConfig);

🔧 高级模式

1. Monad 模式

class Maybe {
  constructor(value) {
    this.value = value;
  }
  
  static of(value) {
    return new Maybe(value);
  }
  
  map(fn) {
    return this.value == null 
      ? Maybe.of(null)
      : Maybe.of(fn(this.value));
  }
  
  flatMap(fn) {
    return this.value == null
      ? Maybe.of(null)
      : fn(this.value);
  }
}
 
Maybe.of(5)
  .map(x => x * 2)
  .map(x => x + 1)
  .map(console.log); // 11

2. Functor 模式

class Box {
  constructor(value) {
    this.value = value;
  }
  
  map(fn) {
    return new Box(fn(this.value));
  }
  
  fold(fn) {
    return fn(this.value);
  }
}
 
Box.of(5)
  .map(x => x * 2)
  .fold(console.log); // 10

🔗 相关链接


参考


javascript 函数式编程 functional-programming patterns