当我们谈论一个函数中的一个函数时,纯函数到底是什么?

时间:2019-04-23 16:27:37

标签: javascript functional-programming pure-function

我了解到,纯函数是不会改变全局状态,周期的函数。如果是这样,函数中的函数可以更改外部函数的状态,并且仍然是纯净的,对吗?

示例:

function func1() {
  let name = "My Name"
  func2()  

  function func2() {
    // alter name here.
  }
}

在上面的示例中,func2仍然是纯净的,因为它不使用任何全局状态。

这就是我的看法,但是我的工作同事认为func2并不纯正,应该这样写:

function func1() {
  let name = "My Name"
  func2(name)  

  function func2(name) {
    // use name here.
  }
}

哪个不好,是因为:

  • 如果v8没有对此进行优化,则CPU将运行更多指令
  • 影射是个坏习惯

问题是:当我们谈论一个函数中的一个函数时,纯函数到底是什么?

4 个答案:

答案 0 :(得分:2)

Purity的定义并不仅仅关心全局变量,它关心的是任何不应该被突变的非本地变量(以及更多)。闭包的外部变量仍然算作非局部变量,不需要全局变量。

因此,如果func2更改了name,那是不纯的。 func1是否还会变得不纯取决于您是否仅考虑外部纯度-只要namefunc2在函数内保持局部,它可能仍然是纯净的。

答案 1 :(得分:1)

pure function是一个满足2个要求的函数:

  1. 给出相同的输入,它将始终返回相同的输出。
  2. 不产生副作用。

Side effects可以定义为“在调用函数之外可观察到的任何应用程序状态更改,除了返回值之外”。


具体来说:

  • 一个修改超出范围(即使不是全局范围)的函数的函数也不是纯函数。

  • 在您的示例中,如果func2在其自己的作用域之外修改了变量,则它不是纯函数:

function func1() {
  let name = "My Name"; // <-- the variable is not in the global scope but, in any case, it is outside the scope of func2
  func2();

  function func2() {
    // alter name here.
  }
}

答案 2 :(得分:0)

  

我了解到,纯函数是不会改变全局状态,周期的函数。

嗯,这太过简单了。一个纯函数应该没有副作用,其二应该只依赖于参数。因此,作为推论,没有状态。您的func1的{​​{1}}属性看起来像是状态。我可以变异吗? name会根据先前的调用产生不同的结果吗?不纯!

当然,func2不纯是无可争议的。您写了“更名”-“名称”不在其范围内。这是副作用。

答案 3 :(得分:0)

我认为值得一提的另一个示例是纯函数

function insert(DB, user) {
    return function() {
        throwIfUserExists(DB, user);
        var savedUser = saveUser(DB, user);
        return savedUser;
    }
}

请注意,当您调用insert时,只要继续发送相同的DBuser,您将收到与该函数返回另一个函数相同的输出-否会发生副作用。