高阶函数

114 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

高阶函数

高阶函数对我们来说是非常重要的,高阶函数的学习是我们之后学习其他的函数的进阶的基础。

什么是高阶函数?

虽然高阶函数名字听起来很高级,但是我们平常经常也会使用到高阶函数,就和闭包一样;但是在我们感觉上一直在用,却不知道什么是高阶函数。什么样的函数可以被称为高阶函数?

  1. 一个函数返回一个函数:
(function() {
    return function() {
        console.log(1)
    }
})()
  1. 一个函数的参数可以接收一个函数
function fn(cb) {
    cb()
}

那么上述的两个条件满足任意一个,就如同示例一样,就可以算是一个简单的高阶函数

我们日常工作中会有哪些场景可能会使用到高阶函数?

1. 拓展方法 会用到高阶函数

举个例子,我们现在有如下代码:

function core(...args) {
    console.log('core', ...args)
}

Q:我们希望在这个代码上进行一些拓展,但是这个代码被很多地方引用,稍有不慎,我们就会引发预料之外的问题。那么该如何解决呢?

  • 方案一:拷贝一份,然后改吧改吧,引用这个新的!
    • 缺点:难以维护,代码多份,如果底层业务修改了可能会改漏掉
    • 优点:保证需要引用的模块代码无误,不会影响到其他的也有引用到的模块
  • 方案二:使用高阶函数
Function.prototype.before =  function(cb) {
    return (...args) => { // 属于运算符
        cb()
        this(...args) // 拓展运算符
    }
}

let newCore = core.before(() => {
    console.log('before')
})

image.png

当然这也很像装饰器模式,代理模式,但是。。。后话后话哈!

2.闭包

闭包的概念,就不需要我再说了吧!

3. 函数柯里化

函数柯里化: 多个参数传入,把他转换为 n个 函数

 function curry(fun) {
    return function curriedFn(...args) {
        // 判断实参和形参的个数
        // 实参 < 形参 那么就返回一个新的函数,接收剩余的参数值
        if(args.length < fun.length){
            return function() {
                // arguments 是伪数组,所以需要使用 Array.from
                return curriedFn(...args.concat(Array.from(arguments)))
            }
        }
        // 实参 >= 形参 那么就直接调用fun,返回执行结果
        return fun(...args)
    }
}

有兴趣仔细了解的同学可以看看:【高速进阶】彻底弄懂柯里化,前端生涯不丢分!