一、函数组合
又叫 饲养函数,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)
