一、函数组合
又叫 饲养函数,compose。由纯函数、偏函数、柯理化函数组成,能够控制数据传递,形成一种有效执行的组合。
左倾:在函数的参数中执行函数
function toUpperCase(str){
return str.toUpperCase()
}
function exclain (str){
return str + '!'
}
//将函数组合起来,返回一个新函数,将组合的函数包裹起来。
function ComposeToUpperCaseAndExclain(toUppercaseFn,ExclainFn){
return function(str){ //关键步骤,返回一个包裹函数组合的函数。
return ExclainFn(toUppercaseFn(str)) //左倾,先执行参数中的函数,再执行函数。
}
}
数据在函数之间(像一个管道)流动处理
抽象组合工具函数
关键点: 函数个数不定,左倾(这里用reduceRight就很方便了)。
function split(str){
return str.split('')
}
function reverse(arr){
arr.reverse()
return arr
}
function join(arr){
return arr.join('~')
}
function toUpperCase(str){
return str.toUpperCase()
}
function exclain(str){
return str + '!'
}
function composeFunction(){
let len = argsArr.length - 1,
argsArr = Array.prototype.slice.call(arguments);
return function(x){
let res = argsArr[len](x);
while(len--){
console.log(res)
res = argsArr[len](res)
}
return res
}
}
let compositionFn = composeFunction(exclain,toUpperCase,join,reverse,split);
function composingFunctionWithReduceRight(){
let args = [...arguments];
return function(x){
console.log(x)
let res = args.reduceRight((accumulotar,elem,index)=>{
console.log(accumulotar,elem,index)
return elem(accumulotar)
},x)
return res
}
}
console.log(compositionFn('not a bum'))
二、结合律 associativity
什么是结合律:在函数组合时,先将参数进行组合,不同组合方式得到的结果是一样的。不管怎么结合,都是对
链式操作的分组串联包裹
function split(str){
return str.split('')
}
function reverse(arr){
arr.reverse()
return arr
}
function join(arr){
return arr.join('~')
}
function composingFunctionWithReduceRight(){
let args = [...arguments];
return function(x){
let res = args.reduceRight((accumulotar,elem,index)=>{
return elem(accumulotar)
},x)
return res
}
}
let compositionFn1 = composingFunctionWithReduceRight(join,reverse,split),
compositionFn2 = composingFunctionWithReduceRight(join,composingFunctionWithReduceRight(reverse,split)),
compositionFn3 = composingFunctionWithReduceRight(composingFunctionWithReduceRight(join,reverse),split);
三、pointfree,执行函数时,无需传入数据参数(返回了一个闭包新函数,新函数会接受自己的数据参数)
function compose (){
let args = [...arguments];
return function(x){
let res = args.reduceRight((accumulotar,elem=>{
return elelm(x)
},x)
return res
}
}
let fn = compose() //调用函数时无需传递数据参数
function classFilter(data){
return data.classes > 20 && data //如果满足条件,会继续走返回最后一个值
}
function isFreeFilter(data){
return data.isFree && data
}
function composingFunctionWithReduceRight(){
let args = [...arguments];
return function(x){
let res = args.reduceRight((accumulotar,elem,index)=>{
return elem(accumulotar)
},x)
return res
}
}
let classesData = [
{ classes: 21, isFree: true},
{ classes: 11, isFree: false},
{ classes: 31, isFree: true},
{ classes: 19, isFree: true},
{ classes: 20, isFree: true}
]
let arr = [],
f = null;
classesData.forEach((item)=>{
f = composingFunctionWithReduceRight(classFilter, isFreeFilter);
f(item) && arr.push(item)
})
console.log(arr)