本文为阅读博文后总结而得,关于博文的网址,由于保存不当,丢失了,作者看到请与我联系,我会将网址添加到文章中
js中函数是一等公民即 js中,函数和其他变量一样,可以把它们存在数组里,当作参数传递,赋值给变量等
为什么我们需要纯函数
比如现在我们有这段代码
function add (a, b) {
return a + b
}
add(1, 2)
add(5, 2)
很好写单元测试吧
describe('add', () => {
it('should return a + b', () => {
add(1, 2).should.equal(3)
})
})
可是如果现在我们要测试的代码是这样的
var C = 0
function addWithC (a, b) {
return a + b + C
}
addWithC(1, 2) // 3
var C=1
addWithC(5, 2) //8
我们发现,待测试的函数其输出结果不再只依赖于输入参数了,还取决于函数运行的时间点。在测试中,我们需要说明两点
- 它所期待的输入是什么
- 输入所对应的输出是什么
当函数不只与输入参数有关,还与运行时间有关时,还怎么写单元测试,我们根本说不清测试要保证该函数取得什么输出结果了。因此我们需要保证,C为一个固定的常数,不能在不同时间取不同的值,它是不可改变的。通过以下方式来保证C为常数
const C = 0
// 等价于
function C () {
return 0
}
这样我们待测试函数便可以改写成这样
function addWithC (a, b) {
return a + b + C()
}
当程序的运行结果都与时间等状态值无关时,我们就成改程序是无状态的。显而易见,一个无状态的程序,所有常量都被替换为返回固定值的函数了,也就是说,我们的程序是由函数构成的。这样,我们也可以说
函数是唯一的一等公民
为了强调,我们换个说法
纯函数是唯一的一等公民。
有时常量的出现也并不影响无状态性
但是有时,常量的出现不会破坏程序的无状态性,而且会为我们带来便利。当常量在函数内部出现时,是没关系的,比如
function addWithC (a, b) {
var c=0
return a + b + c
}
还有一点需要注意,纯函数中如果调用了非纯函数的函数,那么该函数也就不再是纯函数了。