5分钟教你函数式编程

565 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

函数式编程概念

什么是函数式编程?

函数式编程(Function Programming,FP),FP是编程范式之一,我们常说的编程规范还有面向过程编程、面向对象编程。

  • 面向过程编程就是按照过程实现我们想要的功能。
  • 面向对象编程就是把现实中的对象抽离成程序中的类和对象(哦豁,程序员永不单身),通过封装、继承、多态来演示事物时间的联系。
  • 函数式编程是把事物和事物之间的联系抽象到程序世界中(有点抽象,在解释一下!)
    • 通过输入通过某种运算获得相应的输出,程序开发过程中会涉及很多有输入和输出的函数(就是对运算过程中进行抽象,这就是很面向对象有巨大差别的地方,思维模式上的区别)
    • 函数式编程中的函数指的不是程序中的函数,而是运算中的映射关系
    • 相同的输入数据得到相同的输入结果(纯函数)

函数式编程的好处

我们可以看一下一下以下的代码

// 非函数式
let num1 = 2
let num2 = 3
let sum = num1 + num2
console.log(sum)

// 函数式
function add(n1, n2){
    return n1 + n2
}
let sum = add(2,3)
console.log(sum)

我们可以看见我们使用函数式编程会对应进行一些方法函数的封装,这样做的好处是我们之后进行业务开发的时候可以对此进行重用,而且我们的函数都是细粒度的函数,我们可以对此进行重组变成新的方法组合。对与sum我们就可以进行更加便捷的计算而不需要进行多次定义了。(这个就是举个例子,不是那么难的哈)

头等函数(函数是一等公民)

什么是函数式一等公民

MDN Frist-class Function

  • 函数可以储存在变量中
  • 函数作为参数
  • 函数作为返回值
    在JavaScript中函数就是一个普通的对象(可以通过 new Function()进行创建),我们可以把函数储存咋变量/数组中,它还可以作为另一个函数的参数和返回值,甚至我们可以在程序运行的时候通过 new Function('alert(1)')来构造一个新的函数。
  • 把函数赋值给变量
// 函数表达式
let fn =function(){
    console.log('把函数赋值给变量')
}
fn()

这种函数表达式有什么特殊意义呢?我们可以看一下下面的一个示例

const BlohController = {
    index(posts) { return Views.index(posts) }
    show(posts) { return Views.show(posts) }
    create(posts) { return Views.create(posts) }
    update(posts) { return Views.update(posts) }
    emit(posts) { return Views.emit(posts) }
}

我们可以看出,BlohController 这个常量中的一些方法参数是一样的,那我们可以进行这样的改造

const BlohController = {
    index: Views.index
    show: Views.show
    create: Views.create
    update: Views.update
    emit: Views.emit
}

注意,我们把这个方法进行赋值,而不是把方法的调用进行赋值,我们要的是方法本身而不是方法值,所以注意进行修改,会发现我们的代码少了很多!

高阶函数

什么是高阶函数

  • 高阶函数(Higher-order function)

    • 可以把函数作为参数传递给另一个函数
    // 高阶函数 - 函数作为参数
    // 这里用数组的部分方法进行举例
    function forEcah(array, fn){
        for (let i = 0; i < array.length; i++) {
            fn(array[i])
        }
    }
    

    函数作为参数的好处:可以让我们的函数更加灵活,我们调用函数的时候可以让我们不用去考虑函数内部是怎么实现的

    • 可以把函数作为另一个函数的返回结果 其实就是让一个函数生成一个函数
    function makeFn() {
        let msg = 'Hello function'
        return function() {
            console.log(msg)
        }
    }
    // 调用方法1
    const fn = makeFn()
    fn()
    // 调用方法2
    makeFn()
    

    模拟loadsh中的once函数

    function once (fn) {
        let done =false
        return function () {
            if(!done){
                done = true
                return fn.apply(this,arguments)
            }
        }
    }
    

    我们在后面学习闭包和柯里化的时候,会多次使用这个概念的,别担心

使用高阶函数的意义

  • 抽象可以帮我们屏蔽细节,只需要关注我们的目标
  • 高阶函数是用来抽象通用的问题

总结

函数式编程就是对运算过程的抽象,函数式编程的函数不是程序中的函数或者方法而是数学中的函数,他要求相同的输入始终为相同的输出! 函数是一等公民,是柯里化、高阶函数的基础。