函数式编程模式(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)); // 83. 柯里化(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)); // 64. 部分应用(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)); // 105. 闭包(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); // 112. 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🔗 相关链接
参考: