1

原文:Glossary of Modern JavaScript Concepts: Part 1

函数的纯洁性:纯函数、非纯函数、副作用

纯函数

一个函数返回的值只取决于他输入的值,并且没有副作用,那这个函数就是纯函数。这样的函数只要参数是一样的,返回的结果就永远只有一个。以下是一个例子:

function half(x) {
  return x / 2;
}

half(x)函数接受x作为参数,返回x值的一半。如果传入8,那么返回的一定是4.调用一个纯函数时,它的结果可以完全代替这个纯函数,例如我们可以用4代替half(8),无论在哪里使用都不会改变这段代码的最终结果,这就是纯函数的引用透明性
纯函数只依赖它的参数。例如纯函数不能引用它父作用域的变量(除非这个变量作为参数传入)。因此,纯函数无法对它的父作用域作出任何修改。

// some variable that is mutated
let someNum = 8;

// this is NOT a pure function
function impureHalf() {
  return someNum / 2;
}

总结:

  • 纯函数必定带参数
  • 输入一样,输出必定一样
  • 纯函数只改变内部状态不改变外部状态
  • 纯函数无副作用
  • 纯函数不能调用非纯函数

非纯函数

非纯函数会改变它作用域外面的状态(state)。很多有副作用的函数都是非纯函数。

// 非纯函数产生副作用
function showAlert() {
  alert('This is a side effect!');
}

// 非纯函数改变外部变量
var globalVal = 1;
function incrementGlobalVal(x) {
  globalVal += x;
}

// 一个装纯的非纯函数
// 他每次返回的值都不同
function getRandomRange(min, max) {
  return Math.random() * (max - min) + min;
}

JavaScript里的副作用

当函数或表达式修改自己上下文以外的属性,就是产生了副作用。副作用包括调用API、操作DOM、调用alert、数据库操作等。如果一个函数产生副作用,那么他就是非纯的。产生副作用的函数会改变外部变量,因此让人捉摸不透,难以测试。

关于纯洁性的总结

很多高质量代码由调用纯函数的非纯函数组成。这依然在测试和不变性上很有优势。有引用透明性那么就可以写成记忆函数:储存函数结果,然后重用之前储存的结果。这可以判断这个函数是否是纯函数。
更多关于函数纯洁性的资料


ssshooter
3.7k 声望1.8k 粉丝