- 函数的返回结果只依赖于它的参数。
- 函数执行过程里面没有副作用。
const a = 1
const foo = (b) => a + b
let res = foo(2)
console.log(res);
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,纯函数不能修改函数参数
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
}
这里在函数内部申明的对象,因此在函数内部修改的对象,而不是因为外部因素产生的副作用,因此这个函数是一个纯函数