聊聊 Function Composition

定义

Function Composition 是把两个或多个方法合成为一个新方法的过程
Function composition is the process of combining two or more functions to produce a new function. Composing functions together is like snapping together a series of pipes for our data to flow through.

实例

一个常见需求:把下面数组中所有的 type 为 Household 的找出来,计算他们的 price 总和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const expenses = [
{
name: 'Rent',
price: 500,
type: 'Household'
}, {
name: 'Netflix',
price: 5.99,
type: 'Services'
}, {
name: 'Gym',
price: 15,
type: 'Health'
}, {
name: 'Bills',
price: 100,
type: 'Household'
}
];

使用 Pure Function + Pure Function 我们这样处理

1
2
3
4
5
6
7
8
9
10
11
12
13
const typeHousehold = function(arr) {
return arr.filter(function(item) {
return item.type === 'Household';
});
}

const allPriceHousehold = function(arr) {
return arr.reduce(function(total, item) {
return total += item.price;
}, 0);
}

console.log(allPriceHousehold(typeHousehold(expenses))); //600

我们也可以使用 Function Composition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const typeHousehold = function(arr) {
return arr.filter(function(item) {
return item.type === 'Household';
});
}

const sumAll = function(arr) {
return arr.reduce(function(total, item) {
return total += item.price;
}, 0);
}

const compose = function(f, g) {
return function(x) {
return g(f(x));
}
}

const sumAllHousehold = compose(typeHousehold, sumAll);
console.log(sumAllHousehold(expenses)); //600

compose 函数如果用 es6 写的话,更佳简洁

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

工具库

lodash 提供了 .flow 和 .flowRight 方法来获得一个合成过的方法

1
2
3
4
const sumAllHousehold = _.flow([typeHousehold, sumAll]); // 从左到右
const sumAllHousehold = _.flowRight([sumAll, typeHousehold]); //从右到左

console.log(sumAllHousehold(expenses)); //600

Ramda 也提供了 R.compose 方法

1
2
3
const sumAllHousehold = R.compose(sumAll, typeHousehold);

console.log(sumAllHousehold(expenses)); //600

A Gentle Introduction to Composition in JavaScript

What is Function Composition