2.3.2 引用透明和纯函数

当函数没有明显的副作用,且没有隐性的依赖时(或者我们把隐性依赖放在了明面上,也就是调用参数里),函数相同的入参能够输出相同的结果,这样的函数我们称为纯函数(Pure Function)。

在这种理想情况下,如果在环境b中调用funcA(),可以在运行环境中替换成结果r,而不改变b的含义,我们就可以说funcA()对于环境是引用透明的。

引用透明和纯函数这种幂等的形式可以给我们带来很多好处。

首先是代码和结果便于记忆(flux的store)和缓存(_.memoize),其中缓存是搭建大型项目的一个重要内容。其次,这将增加测试的可行性。每个引用透明的过程都可以看作一个黑盒单元。纯函数的组合串联仍然是纯函数,这些黑盒也便于组合。最后,代码模块化效果会更好,因为状态可变动的位置在收敛,所以代码会变得更健壮。我们可以通过代码清单2-8对副作用和状态的收敛进行理解。

代码清单2-8 JavaScript副作用和状态的收敛


// 副作用(状态改变)更容易
if (this.newVersion) {
  try {
    const titleName = this.currentPageInfo.name
    window.jsBridge.page.setTitle({title: titleName},   // 对外操作
    function (err, res) {
      if (err) {
        console.log('set title error')  // 对外操作
      } else {
        console.log('set title succeed')
        window.jsBridge.showToast(res)
        this.title = res
      }
    })
  } catch (e) {
    console.error('修改title失败')
  }
}

// 减少可变的状态
this.x = 2
function f(y) { return this.x + y }
function fplus(y) { return f.bind({x: 1})(y) }
var g1 = f(2)
var g2 = fplus(2)
// got 4 3