跳到主要内容

函数式工具库

除了原生 JavaScript 方法,还有许多优秀的函数式编程库可以简化开发。

Lodash/FP

Lodash 的函数式编程版本,所有函数都自动柯里化。

const fp = require('lodash/fp');

// 自动柯里化
const mapDouble = fp.map(x => x * 2);
mapDouble([1, 2, 3]); // [2, 4, 6]

// 数据在最后,便于组合
const process = fp.pipe(
fp.filter(x => x > 0),
fp.map(x => x * 2),
fp.sum
);

process([1, -2, 3, -4, 5]); // 18

常用函数

const fp = require('lodash/fp');

// 对象操作
fp.get('name', { name: 'John', age: 25 }); // 'John'
fp.set('age', 30, { name: 'John' }); // { name: 'John', age: 30 }
fp.pick(['name', 'email'], user);
fp.omit(['password'], user);

// 数组操作
fp.groupBy('category', items);
fp.sortBy('age', users);
fp.uniq([1, 2, 2, 3, 3, 3]); // [1, 2, 3]
fp.flatten([1, [2, 3], [4]]); // [1, 2, 3, 4]

// 函数组合
fp.pipe(f, g, h)(x); // h(g(f(x)))
fp.compose(h, g, f)(x); // h(g(f(x)))

Ramda

专门为函数式编程设计的库,所有函数都自动柯里化。

const R = require('ramda');

// 柯里化
const add = R.add;
const add5 = add(5);
add5(3); // 8

// 组合
const process = R.pipe(
R.filter(R.gt(R.__, 0)),
R.map(R.multiply(2)),
R.sum
);

process([1, -2, 3, -4, 5]); // 18

Ramda 特色

const R = require('ramda');

// 占位符 R.__
const subtract5 = R.subtract(R.__, 5);
subtract5(10); // 5

// 逻辑函数
const isAdult = R.propSatisfies(R.gte(R.__, 18), 'age');
R.filter(isAdult, users);

// 条件函数
const getStatus = R.cond([
[R.propEq('score', 100), R.always('Perfect')],
[R.propSatisfies(R.gte(R.__, 60), 'score'), R.always('Pass')],
[R.T, R.always('Fail')]
]);

// 透镜(Lens)
const nameLens = R.lensProp('name');
R.view(nameLens, { name: 'John' }); // 'John'
R.set(nameLens, 'Jane', { name: 'John' }); // { name: 'Jane' }

Immutable.js

Facebook 开发的不可变数据结构库。

const { Map, List, fromJS } = require('immutable');

// Map
const map = Map({ a: 1, b: 2 });
const newMap = map.set('b', 3);
map.get('b'); // 2 (原对象未改变)
newMap.get('b'); // 3

// List
const list = List([1, 2, 3]);
const newList = list.push(4).unshift(0);
// List [0, 1, 2, 3, 4]

// 深度转换
const deep = fromJS({ users: [{ name: 'John' }] });
deep.getIn(['users', 0, 'name']); // 'John'
const updated = deep.setIn(['users', 0, 'name'], 'Jane');

库的选择

特点适用场景
Lodash/FP功能全面,文档丰富通用项目
Ramda函数式优先,数学严谨纯函数式编程
Immutable.js不可变数据结构React/Redux 项目

最佳实践

  1. 选择合适的库 根据项目需求选择
  2. 学习组合模式 掌握 pipe 和 compose
  3. 利用柯里化 创建可复用的函数
  4. 保持纯函数 避免副作用