reducer(概括函数)这种函数的名称,是由数组的一个迭代方法reduce(概括)而来,你能够参考MDN中的相关说明:数据库
在JS语言中的数组reduce(概括)这个方法是一种应用于特殊状况的迭代方法,它能够藉由一个回调(callback)函数,来做先后值两相运算,而后不断缩减数组中的成员数量,最终返回一个值。reduce(概括)并不会更动做为传入的数组(调用reduce的数组),因此它也没有反作用。一个简单的例子以下:数组
const aArray = [0, 1, 2, 3, 4, 5] const sum = aArray.reduce(function(pValue, value, index, array){ return pValue + value }) console.log(sum) // 15
数组的reduce(概括)方法,还有另外一种语法样式,是带有初始值的,这会比较接近Redux中的reducer样式,以下面的例子:浏览器
const initialState = 0 const sum = [1, 2, 3, 4, 5].reduce(add, initialState) function add(a, b) { // `a` 表明前一个状态 // `b` 表明目前在数组中的项目 return a + b } console.log(sum) // 15
reduce(概括)方法具备分散运算的特色,常见于下面几种应用之中:缓存
两相比较最后取出特定的值(最大或最小值)框架
计算全部成员(值),总合或相乘dom
其它须要两两处理的状况(组合巢状数组等等)异步
不过,Redux中的reducer与数组中的reduce方法并不相同,其中最大的差别,是reducer并非对一整个列表进行概括运算,而是对一个action(动做)与目前的state进行概括运算,回传出新的state。函数
当一个函数是纯函数时,咱们能够说
输出
只取决于输入
测试
对于函数来讲,具备反作用表明着可能会更动到外部环境,或是更动到传入的参数值。函数的区分是以 纯(pure)函数 与 不纯(impure)函数 二者来区分,但这不光只有无反作用的差别,还有其余的条件。纯函数(pure function)即知足如下三个条件的函数,如下的定义是来自于Redux的概念:优化
给定相同的输入(传入值),必定会返回相同输出值结果(返回值)
不会产生反作用
不依赖任何外部的状态
一个典型的纯函数的例子以下:
const sum = function(value1, value2) { return value1 + value2 }
套用上面说的条件定义,你能够用下面观察来理解它是否是一个纯函数:
只要每次给定相同的输入值,就必定会获得相同的输出值: 例如传入1与2,就必定会获得3
不会改变原始输入参数,或是外部的环境,因此没有反作用
不依頼其余外部的状态,变量或常量
那什么又是一个不纯的函数?看如下的例子就是,它须要依赖外部的状态/变量值:
let count = 1 let increaseAge = function(value) { return count += value }
在JavaScript中不纯函数很常见,像咱们一直用来做为输出的console.log
函数,或是你可能会在不少例子看到的alert
函数,都是"不"纯函数,这类函数一般没有返回值,都是用来做某件事,像console.log
会更动浏览器的主控台(外部环境)的输出,也算是一种反作用。
每次输出值都不一样的不纯函数一类,最典型的就是Math.random
,这是产生随机值的内建函数,既然是随机值固然每次运行的返回值都不同。
例如在数组的内建方法中,有一些是有反作用,而有一些是无反作用的,这个部份须要查对应API才可以清楚。不会改变传入的数组的,会在做完某件过后返回一个新数组的方法,就是无反作用的纯函数(方法),而会改变原数组就算是不纯函数(方法)了。
下面是两个在数组中做一样事情的不一样方法,都是要取出只包含数组的前三个成员的数组。一个用splice
,另外一用是slice
,看起来都很像,连这两个方法的名称都很像,但倒是彻底属于不一样的种类:
// 不纯粹(impure),splice会改变到原数组 const firstThree = function(arr) { return arr.splice(0,3) } // 纯粹(pure),slice会返回新数组 const firstThree = function(arr) { return arr.slice(0,3) }
其余有许多内建的或经常使用的函数都是免不了有反作用的,例如这些应用:
会改变传参(对象、数组)的函数(方法)
时间性质的函数,setTimeout等等
I/O相关
数据库相关
AJAX
纯函数固然有它的特别的优势:
代码阅读性提升
较为封闭与固定,可重覆使用性高
输出输入单纯,易于测试、调试
由于输入->输出结果固定,能够缓存或做记忆处理,在高花费的应用中可做提升运行效率的机制
最后,并非说有反作用的函数就不要使用,并且要很清楚的理解这个概念,而后尽量在你本身的撰写的通常功能函数上使用纯函数,以及让必要有反作用的函数获得良好的管控。如今已经有一些新式的函数库或框架(例如Redux),会特别强制要求在某些地方只能使用纯函数,而具备反作用的不纯函数只能在特定的状况下才能使用。
注: 虽然在反作用与纯函数的介绍中,咱们有提到一些调用外部API(console.log/alert)、时间(Date())、随机(Math.random)也属于有反作用的调用,但以等级来区分它们只算是"轻度"或"微量"的反作用,这些在reducer或Action Creators能不能用?答案是能够用但也不要用,它会影响到纯函数的一些优化。以在反作用的主题来讲,异步运行才是"中度"或"通常"等级的反作用,咱们谈到反作用一般是指这个等级的。固然也有"重度"等级的反作用,那是另外一个层次的特殊应用状况讨论,例如组合出来的复杂异步运行流程结构。