乐趣区

关于javascript:纯函数

定义

简略来说,一个函数的返回后果只依赖于它的参数,并且在执行过程外面没有副作用,咱们就把这个函数叫做纯函数。

实例

const a = 1
const foo = (b) => a + b
foo(2) // => 3

foo 函数 不是纯函数,因为它返回的后果依赖于内部变量 a,咱们在不晓得 a 的值的状况下,并不能保障 foo(2) 的返回值是 3。尽管 foo 函数的代码实现并没有变动,传入的参数也没有变动,但它的返回值却是不可意料的,当初 foo(2) 是 3,可能过了一会就是 4 了,因为 a 可能产生了变动变成了 2。

const a = 1
const foo = (x, b) => x + b
foo(1, 2) // => 3

当初 foo 的返回后果只依赖于它的参数 x 和 b,是纯函数 ,foo(1, 2) 永远是 3。明天是 3,今天也是 3,在服务器跑是 3,在客户端跑也 3,不论你内部产生了什么变动,foo(1, 2) 永远是 3。只有 foo 代码不扭转,你传入的参数是确定的,那么 foo(1, 2) 的值永远是可意料的。
这就是纯函数的第一个条件:一个函数的返回后果只依赖于它的参数。
函数执行过程没有副作用
一个函数执行过程对产生了内部可察看的变动那么就说这个函数是有副作用的。

const a = 1
const foo = (obj, b) => {return obj.x + b}
const counter = {x: 1}
foo(counter, 2) // => 3
counter.x // => 1

咱们把原来的 x 换成了 obj,我当初能够往里面传一个对象进行计算,计算的过程外面并不会对传入的对象进行批改,计算前后的 counter 不会产生任何变动,计算前是 1,计算后也是 1,它当初 是纯函数

const a = 1
const foo = (obj, b) => {
  obj.x = 2
  return obj.x + b
}
const counter = {x: 1}
foo(counter, 2) // => 4
counter.x // => 2

当初状况产生了变动,我在 foo 外部加了一句 obj.x = 2,计算前 counter.x 是 1,然而计算当前 counter.x 是 2。foo 函数的执行对外部的 counter 产生了影响,它产生了副作用,因为它批改了内部传进来的对象,当初它 不是纯函数

const foo = (b) => {const obj = { x: 1}
  obj.x = 2
  return obj.x + b
}

尽管 foo 函数外部批改了 obj,然而 obj 是外部变量,内部程序基本察看不到,批改 obj 并不会产生内部可察看的变动,这个函数是没有副作用的,因而它是一个 纯函数


除了批改内部的变量,一个函数在执行过程中还有很多形式产生内部可察看的变动,比如说调用 DOM API 批改页面,或者你发送了 Ajax 申请,还有调用 window.reload 刷新浏览器,甚至是 console.log 往控制台打印数据也是副作用。

纯函数很严格,也就是说你简直除了计算数据以外什么都不能干,计算的时候还不能依赖除了函数参数以外的数据。

总结

为什么要殚精竭虑地构建纯函数?因为纯函数十分“靠谱”,执行一个纯函数你不必放心它会干什么好事,它不会产生不可意料的行为,也不会对外部产生影响。不论何时何地,你给它什么它就会乖乖地吐出什么。如果你的应用程序大多数函数都是由纯函数组成,那么你的程序测试、调试起来会十分不便。

退出移动版