和纯函数相反的就是“不纯函数”(Impure Function),一个函数之所以不纯,可能做了下面这些事情:
·改变全局变量的值。
·改变输入参数引用的对象,就像上面不是纯函数的arrayPush实现。
·读取用户输入,比如调用了alert或者confirm函数。
·抛出一个异常。
·网络输入/输出操作,比如通过AJAX调用一个服务器的API。
·操作浏览器的DOM。
上面还只是不纯函数的一部分表现,其实,有一个很简单的判断函数纯不纯的方法,就是假设将一个函数调用替换为一个预期返回的常数,程序运行结果是否一样。
数据不可变(Immutable)是函数式编程非常重要的一个概念,对于刚刚接触这个概念的朋友,可能会觉得莫名其妙,因为众所周知程序就是用代码指令在操作数据,如果数据不能变化,那一个程序又能够干什么有用的事情?
程序要好发挥作用当然是要产生变化的数据,但是并不意味着必须要去修改现有数据,替换方法是通过产生新的数据,来实现这种“变化”,也就是说,当我们需要数据状态发生改变时,保持原有数据不变,产生一个新的数据来体现这种变化。
不可改变的数据就是Immutable数据,它一旦产生,我们就可以肯定它的值永远不会变,这非常有利于代码的理解。
其实,你可能已经体会到了Immutable数据类型的好处,在JavaScript中,字符串类型、数字类型就是不可改变的数据,使用这两种类型的数据给你带来的麻烦比较少。相反,JavaScript中大部分对象都是可变的,比如JavaScript自带的原生数组类型,数组的push、pop、sort函数都会改变一个数组的内容,由此引发的bug可不少。这些不纯的函数导致JavaScript天生不是一个纯粹意义上的函数式编程语言。