组合函数
组合(Compose)函数是在JavaScript开发过程中一种对函数的使用技巧、模式:
比如我们现在需要对某一个数据进行函数的调用,执行两个函数fn1和fn2,这两个函数是依次进行的;
那么如果每次我们都需要进行两个函数的调用,操作上就会显得很重复;
那么是否可以将这两个函数组合起来,自动依次调用呢?
这个过程就是对函数的组合,我们称之为 组合函数(Compose Function)。
一、简单的认识一下组合函数
场景假设:需要将N个数字分别进行调用double方法乘以2,再调用square方法平方。
示例代码如下:
// 普通情况下: function double (num) { return num * 2 } function square (num) { return num * num } var count = 10 var result = square(double(count)) console.log(result) // 组合函数情况下: function composeFn (d, s) { return function (count) { return s(d(count)) } } var newFn = composeFn(double, square) var result2 = newFn(10) console.log(result2)
有的小伙伴要疑惑了我明明普通情况下就能完成,使用组合函数还需要声明两个方法,在进行组合才能使用,我费那老劲干啥? 当需要进行这样操作的数字多的时候,肯定是组合函数使用起来方便。
二、手动实现一个通用的组合函数(烧脑版)
看了上面的代码是不是感觉 组合函数很简单呀,接下来就带大家实现一个通用的组合函数。代码不多,但理解可能需要点时间,来看看怎么实现的吧。
实现步骤:
首先创建一个myCompose函数,接收多个函数类型的参数使用…fns表示;
判断传入参数的类型是否全部都为函数类型,不是则抛出异常报错;
myCompose函数内部返回一个函数compose,接收多个参数,使用…args表示;
函数compose内部定义一个result,之后判断传入参数的数量,如果是多个,则result为数组类型,如果为一个则result为一个值;
之后根据参数的数量选择if或else中执行,分别将参数传入fns的函数中执行调用,最后将result值返回。
代码示例:
完整代码如下:
function myCompose (...fns) { // 1.首先看一下传入函数的个数,并判断传入的全部参数的类型都是函数类型,不是的话就抛出异常 var length = fns.length for (var i = 0; i < length; i++) { if (typeof fns[i] !== 'function') { throw new TypeError('Expected arguments are functions') } } // 2.返回一个compose函数 return function compose (...args) { // 定义一个空数组result,判断参数的数量,如果为空则置为undefined var result = args.length > 1 ? [] : undefined // 如果args参数的数量大于1执行if中的语句 if (args.length > 1) { for (var i = 0; i < args.length; i++) { var _index = 0 var r = fns[_index].call(this, args[i]) while (++_index < length) { r = fns[_index].call(this, r) result.push(r) } } } else { var index = 0 // 此时的result为第一个函数执行的结果 result = length ? fns[index].apply(this, args) : args // 使用while将第一个函数执行的结果传递给第二个函数,获取到结果,以此传递下去,最终返回result while (++index < length) { result = fns[index].call(this, result) } } return result } } function double (num) { return num * 2 } function square (num) { return num * num } // 传入两个函数参数 var newFn = myCompose(double, square) // 传入一个参数调用newFn函数 var result1 = newFn(10) // 传入多个参数调用newFn函数 var result2 = newFn(10, 20, 30) console.log(result1)// 400 console.log(result2)// [ 400, 1600, 3600 ]
看完是不是打破了对JavaScript函数的使用技巧的认知。点个赞再走吧。