函数式编程 -- 纯函数

什么是纯函数?

纯函数:相同的输入永远会得到相同的输出,而且没有任何可观察的副作用

// 纯函数slice和不纯函数splice
let array=[1,3,6,8]
//slice不改原数组,第次输出结果是一样的,是纯函数
console.log(array.slice(0,3))
console.log(array.slice(0,3))
console.log(array.slice(0,3))
// 输出:
// [1,3,6]
// [1,3,6]
// [1,3,6]

//splice改变了原数组,每次输出结果不一样,不是纯函数
console.log(array.splice(0,3))
console.log(array.splice(0,3))
console.log(array.splice(0,3))
// 输出:
// [1,3,6]
// [8]
// []

纯函数的好处

  • 因为纯函数每次都能够得到相同的结果,所以可以把结果缓存起来

    • 在lodash中有记忆函数,可以缓存结果

      const require('lodash')
      function getArea(r){
        console.log(r)
        return Math.PI*r*r
      }
      
      let getAreaWithMemory=__.memoize(getArea)
      console.log(getAreaWithMemory(4))
      console.log(getAreaWithMemory(4))
      console.log(getAreaWithMemory(4))
      // 输出:
      // 4
      // 50.26548245743669
      // 50.26548245743669
      // 50.26548245743669
      
    • 从结果可以看出,只有第一次输出了4,其它再次都是直接输出的缓存结果

    • 具体的memoize方法是怎么实现的,现在来模拟一下

      // 模拟 memoize 方法
      function memoize(f){
        let cache = {}
        return function(){
          let key = JSON.stringify(arguments)
          cache[key] = cache[key] || f.apply(f,arguments)
          return cache[key]
        }
      }
      
      // 测试
      
      let getAreaWithMemory = memoize(getArea)
      console.log(getAreaWithMemory(4))
      console.log(getAreaWithMemory(4))
      console.log(getAreaWithMemory(4))
      // 输出:
      // 4
      // 50.26548245743669
      // 50.26548245743669
      // 50.26548245743669
      
      
  • 纯函数让测试变得更方便,因为其没有副作用,不用考虑结果之外的影响

  • 纯函数不需要访问共享的内存数据,所有在并行环境中可以任意运行纯函数(es6以后新增了Web Worker,Web Worker可以开启新的线程)

函数的副作用

  • 什么是函数的副作用?

    // 不纯的函数
    let mini = 18
    function checkAge(age){
      // 这里函数依赖外部变量mini,当外部变量mini发生改变时,
      // 会对函数checkAge的结果产生影响,无法保证相同的输入得到相同的输出,
      // 所以此函数不是纯函数,
      // 由于外部产生的影响就是此函数的副作用
      return age >= mini
    }
    
  • 函数的副作用的来源

    • 配置文件
    • 数据库
    • 获取用户的输入
    • ...
      所有外部交互都有可能带来副作用,副作用会使方法通用性降低而变得不易扩展或重用,同时出会为程序带来安全隐患和不确定性,副作用不是可以完全避免的,我们在开发过程应该尽可能的把它控制在可控范围内
原文地址:https://www.cnblogs.com/MissSage/p/14875844.html