高阶函数理解

·  阅读 279

高级函数概念理解

  1. 一个函数的参数为函数
  2. 一个函数返回值为函数

由此衍生一个问题,日常开发中如何对一个函数方法进行拓展?

此时我们就可以采用高阶函数去实现

高阶函数

首先我们定义一个函数方法

function study(...args) {
    console.log('当前我正在' + args)
}
复制代码

我想在此函数上面拓展玩游戏的方法怎么办呢?

首先我们在原型链上定义一个拓展方法before,定义一个玩游戏的方法play函数

Function.prototype.before = function (beforeFn) {
    return (...args) => {
        beforeFn();
        this(...args)
    }
}

const play = (...args) => {
    console.log('当前我正在' + args)
}
复制代码

之后我们如何去玩呢?

let newFn = study.before(() => {
    play('玩游戏')
})

newFn('学习')
复制代码

请看结果,这样我们就实现了拓展,你学废了没有?

image.png

柯理化函数

其实柯理化函数就是一个高阶函数,其含义就是给函数分步传递参数,每次传递部分参数,并返回一个更具体的函数接收剩下的参数,这中间可以嵌套多层这样的接收部分参数的函数,直至返回最后的结果。

柯理化函数简单理解就是让一个函数变得更具体些.

举个简单的栗子:

//原函数
function add(a,b,c){
    return a+b+c
}
add(1,2,3)

//柯理化函数
function addCurrying(a){
    return function(b){
        return function(c){
            return a+b+c
        }
    }
}
//调用柯理化函数(充分利用了闭包的特性实现)
addCurrying(1)(2)(3)
复制代码

实现通用性函数

function currying(fn, args) {
    //获取形参个数,即fn正常运行时所需参数的长度
    let fnLen = fn.length;
    //收集函数所传其他参数
    args = args || []
    return function () {
        //将参数转化为数组
        let _args = [].slice.call(arguments)
        //将上次的参数与当前参数进行合并
        Array.prototype.unshift.apply(_args, args);
        //可替换成  _args = [...args, ..._args];
        //把args数组加入到_args数组的前面,注意执行顺序
        
        //参数不够则继续收集参数
        if (_args.length < fnLen) {
            return currying.call(null, fn, _args)
        }
        //如果参数满足,则直接执行
        return fn.apply(null, _args)
    }
}
复制代码

下面我们要去测试一下,就简单写个测试函数

//判断类型
function isType(type, value) { 
    return Object.prototype.toString.call(value) === `[object ${type}]`
}
let isString = curry(isType)('String');
let isNumber = curry(isType)('Number');
console.log(isString('abc'));
console.log(isNumber('abc'));
复制代码

由此我们可以得出柯理化另一个优点,通过参数的拆分实现了不同功能的函数

测试结果

image.png

分类:
前端
收藏成功!
已添加到「」, 点击更改