函数式编程概述

作者: 子皙丶 | 来源:发表于2019-12-07 15:32 被阅读0次

    1. 函数式编程的大概背景

    • Javascript作为一种典型的多范式编程语言,这两年随着React Vue的火热,函数式编程的概念也开始更加流行
    • Rxjs、loadsh、underscore等多种开源库都使用了函数式的特性

    2. 纯函数的定义

    • 定义

    对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不用依赖外部环境的状态。

    举个栗子:
    在Js中,对于数组的操作有些是纯的,有些不是纯的。

    var arr =  [1,2,3,4,5]
    
     //纯函数
    arr.slice(0,3)  // result : [1,2,3]
    arr.slice(0,3)  // result : [1,2,3]
    
    //非纯函数
    arr.splice(0,3)  //  result : [1,2,3]
    arr.splice(0,3)  // result : [4,5] 
    
    • 多次调用传入的参数相同会得到相同的结果
    • 闭关锁国,不受外部的影响

    3. 函数式编程为何排斥不纯的函数

    非纯函数中,函数的行为需要由外部的系统环境决定,也就是说此函数行为不仅取决于输入的参数,还取决与外部的变量。

    举个栗子:

     var timeOfLife = 20
     //纯函数
    function test(){
      return age > 20
    }
    //非纯函数
    function test(){
      return age > timeOfLife
    }
    

    非纯函数中受外部变量timeOflife的影响,这种对于外部状态的依赖,是造成系统复杂性大大提高的主要原因。
    如何解决呢?

    4. 函数柯里化

    • 定义

    向函数传递一部分参数来调用塔,让它返回一个函数去处理剩下的参数。

    注:事实上柯里化是一种“预加载”函数的方法,通过传递较少的参数,得到一个已经记住了这些参数的新函数,某种意义上讲,这是一种对参数的“缓存”,是一种非常高效的编写函数的方法。

    解决上述代码中的问题:

    var timeOflife = 20
    function test(timeOflife){
      return function(age){
        return age > timeOflife
      }
    }
    var testing = test(20)
    testing(18)  // result : false
    

    5. 函数组合

    • 使用函数组合的目的

    为了避免写出不优雅的包菜式的代码,例如:h(g(f(x))),我们需要用到函数组合

    • 定义

    定义N个纯函数,像拼积木一样优雅的将N个函数组合起来。

    举个栗子:

    var compose = function(f,g){
      return function(x){
        return f(g(x))
      }
    }
    
    var mult = function(x){
      return x * 5
    }
    
    var add = function(x){
      return x + 1
    }
    
    compose(mult,add)(2)   // result : 15
    
    • 定义两个纯函数 mult 和 add
    • 使用组合函数的方式,将两个纯函数组合成compose,对外调用compose就可以显示功能。

    6. 声明式和命令式

    • 命令式代码

    通过编写一条有一条的命令,让计算机执行一些动作,其中一般会涉及许多繁杂的细节。一般初级编程人员编码时使用比较多。

    举个栗子:

    var rest = []
    var arr = [4,9,16,25]
    for(var i = 0 ; i < arr.length ; i++){
      if(rest.indexOf(arr[i]) === -1){
        rest.push(Math.sqrt(arr[i]))
      }
    }
    

    函数的目的就是将arr数组中的数据开方放到rest中去,但是用命令式的代码就会发现,代码复杂不易理解,也不够优雅。

    • 声明式代码

    通过写表达式的方式,声明我们想干什么,而不是通过一步步的指示。声明式代码,相比较函数式编程的一个明显的好处-- 编写简洁、结构优雅、优化代码时更能专注、业务和功能能够分离。

    举个栗子:

    var arr = [4,9,16,25]
    var rest = arr.map(Math.sqrt)
    

    7. 总结

    • 函数对于外部状态的依赖,是造成系统复杂性大大提高的主要原因。
    • 代码书写中让函数尽可能的纯净。(也就是我们上面说的写纯函数,然后使用组合的方式,将纯函数组合起来已达到实现功能的目的)
    • 函数式编程不是万能的,它与OOP一样,只是一种编程规范
    • 为降低软件复杂度,OOP的方式是靠良好的封装、继承、多态、以及接口定义。函数式编程则是靠组合、柯里化等技术。

    简而言之:函数式编程就是通过柯里化、组合等技术将纯函数灵活运用已达到实现功能的目的。

    相关文章

      网友评论

        本文标题:函数式编程概述

        本文链接:https://www.haomeiwen.com/subject/tzkugctx.html