JavaScript函数式编程-组合与管道05
1.组合compose:
在了解组合概念之前,先来理解Unix
理念。
- 每个程序只做好一件事情,为了完成一项新的任务,
重新构建
要好于在复杂的的就程序中添加新属性
- 每个程序的
输出
应该是另一个尚未可知的程序的输入
。

🚀 下面来说下关于compose
的具体实现:
1.1-composeN组合函数的实现思路:
-
composeN
函数接收多个函数为参数,返回一个接收初始值value(作为reduce函数的初始值)
的函数 -
传入的多个函数的执行顺序为
从右到左(通过funcs.reverse()来实现)
,然后上一次的执行函数的结果
会作为下一个函数的输入
继续执行...
//reduce函数
const reduce = (array,fn,initVal)=>{
let accumlator;
if(initVal !== undefined){
accumlator = initVal;
}else{
accumlator = array[0];
}
if(initVal === undefined){
for(let i = 1;i<array.length;i++){
accumlator = fn(accumlator,array[i]);
}
}else{
for (const value of array){
accumlator = fn(accumlator,value);
}
}
return [accumlator]
};
//composeN组合函数
const composeN = (...funcs) => (value) => reduce(funcs.reverse(),(acc,func) => func(acc),value);
1.2-compose
的使用:
🚀 例子1:
//compose组合的简单使用
let number = compose(Math.round,parseFloat);
console.log("Number is ",number("3.56"));
//控制台结果为4
- 实际上等同于
number = (value) => Math.round(parseFloat(c))
;parseFloat
执行后的结果作为了Math.round
的参数
1.3-引入curry
与partial
:
当函数接收一个参数
时,才能将两个函数完成组合,但是实际开发中的情况远不止如此,还存在多参数
的情况。
以之前在数组的函数式编程中封装好的map
和filter
函数为例,都接收两个参数
:
- 要被操作的数组
- 操作数组的函数
let books = [
{
"id": 111,
"title": "css",
"author": "张大",
"rating": [4.9],
"reviews": [{good : 4 , excellent : 12}]
},
{
"id": 222,
"title": "JavaScript",
"author": "王二",
"rating": [4.5],
"reviews": []
},
{
"id": 333,
"title": "vuejs",
"author": "霍三",
"rating": [4.9],
"reviews": []
},
{
"id": 444,
"title": "javascript测试",
"author": "无名",
"rating": [4.2],
"reviews": [{good : 14 , excellent : 12}]
}
];
//筛选过滤的条件函数
let filterOutStandingBooks = (book) => book.rating[0] === 5;
let filterGoodBooks = (book) => book.rating[0] > 4.5;
let filterBadBooks = (book) => book.rating[0] < 3.5;
//获取的内容函数
let projectTitleAndAuthor = (book) => { return {title: book.title,author:book.author} }
let projectAuthor = (book) => { return {author:book.author} }
let projectTitle = (book) => { return {title: book.title} }
//通过偏应用处理,将多参数函数处理为单参数函数
let queryGoodBooks = partial(filter,undefined,filterGoodBooks);
let mapTitleAndAuthor = partial(map,undefined,projectTitleAndAuthor);
//实际使用
let titleAndAuthorForGoodBooks = compose(mapTitleAndAuthor,queryGoodBooks);
console.log("前端推荐好书的名字和作者",titleAndAuthorForGoodBooks(books));
🚀 结果如下:
前端推荐好书的名字和作者[
{
title:'css',
author:'张大'
},
{
title:'vuejs',
author:'霍三'
}
]
- 因为
map、filter、reduce函数以及partial函数
等都没有在代码中体现。 - 组合的思想就是把小函数组合成一个大函数。
- 对于
partial
,这里是通过partial
将map和filter封装成了一个只接受一个参数的数组的函数,分别是queryGoodBooks
、mapTitleAndAuthor
。 - 需要感受的就是拼
接乐高积木
的感觉
2.管道pipe:
通过上面compose
的封装,了解到compose函数的数据流
的运行机制:从右至左
pipe
是与之数据流向相反的-从左到右
,pipe
的实现上来说,也和compose
只是细微的差别:
const composeN = (...funcs) => (value) => reduce(funcs,(acc,func) => func(acc),value);
-
将
reduce
的参数funcs
的reverse
去掉,便是pipe
-
compose
和pipe
其实做的事情基本相同,只是数据的流向相反
而已
最后关于函子的部分可能就不做介绍了,后续可能会再找时间添加进来,关于函数式编程的部分就到这里了。
转载自:https://juejin.cn/post/7068902552846204965