• 函数式编程 -- 纯函数


    什么是纯函数?

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

    // 纯函数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
      }
      
    • 函数的副作用的来源

      • 配置文件
      • 数据库
      • 获取用户的输入
      • ...
        所有外部交互都有可能带来副作用,副作用会使方法通用性降低而变得不易扩展或重用,同时出会为程序带来安全隐患和不确定性,副作用不是可以完全避免的,我们在开发过程应该尽可能的把它控制在可控范围内
  • 相关阅读:
    内部类
    抽象类与接口
    多态
    继承
    封装
    创建对象的内存分析
    构造器
    面向对象 类与对象
    uniapp跳转
    uniapp-组件引用错误,仅支持 import 方式引入组件
  • 原文地址:https://www.cnblogs.com/MissSage/p/14875844.html
Copyright © 2020-2023  润新知