compose 函数与 pine 函数

compose 函数与 pine 函数

  • 1. compose 函数
      • 1.1 概念
      • 1.2 案例
      • 1.3 分析
      • 1.4 实现 compose 函数
          • 1.4.1 思路
          • 1.4.2 方案
  • 2. pipe 函数

1. compose 函数

1.1 概念

compose 函数是从右往左执行。compose 函数是一个高阶函数,第一阶参数分别为不同的函数,第二阶参数为第一阶参数中最右边的函数所需参数,执行最右边函数之后,将其返回值作为参数执行右边倒数第二个函数,再将其返回值作为参数,执行右边倒数第三个函数,以此类推。直到执行完所有函数,并返回第一个函数的执行结果。

1.2 案例

如:compose(f1,f2,f3)(1,2)

function f1(a){
   return a+10
}
function f2(a){
   return a+10
}
function f3(a,b){
   return a+b
}

1.3 分析

首先 compose 函数的第二阶参数(1,2)作为参数调用第一阶参数最右边函数也就是f3。返回值为3
其次将3作为参数执行右边倒数第二个函数f2。返回值为 3+10=13
最后将13作为参数执行最后一个函数f1。返回值为 13+10=23

1.4 实现 compose 函数

1.4.1 思路
  1. 要分别执行 f1,f2,f3 函数,而这些函数在 arguments 对象中。所以可以循环执行 arguments 对象。
  2. 因为是从右到左执行。所以索引值应该是从大到小递减的。
  3. 因为是高阶函数,所以在 compose 中会有一个闭包。而在这个闭包中的参数就是 arguments 对象中最右边函数所需参数。
  4. 执行完最右边函数,将结果保存下来作为参数执行倒数第二个函数,以此类推。
1.4.2 方案

使用循环:

function compose(...args) {
    var index = args.length-1;
    var result;
    return function (...arg) {
        result = args[index].apply(this,arg);
        while (index>0){
            index--;
            result = args[index].apply(this,[result]);
        }
        return result;
    }
}

使用 reduce:

function compose(...args) {
    return args.reduce((a, b)=> {
    //在执行 args.reduce 时分别存储了
    //a(f0),b(f1) | a(f...),b(f2) | a(f...),b(f3) 
    //到后面的闭包内。所以执行闭包的时候最开始 b 就是f3,到最后 a 就是f0。
        return function (...arg) {
           return  a(b(...arg));
        }
    })
}

2. pipe 函数

pipe 函数与 compose 函数相反,是从左到右执行。
比如当调用 pipe(x, f1, f2) 时,返回f2(f1(x))。

实现方案也有两种。

使用循环:

function pipe(x, ...fns){
	let total = x;
	for(let f of fns){
		total = f(total)
	}
	return total;
}

使用 reduce:

const pipe = function(x, ...fns) {
	fns.reduce((y, f) => f(y), x);
}

测试:

pipe(10, f1, f2) === 30

function f1(a){
   return a+10
}
function f2(a){
   return a+10
}

你可能感兴趣的:(#,JavaScript,进阶)