大家好,欢迎来到IT知识分享网。
compose()合并函数核心:每次的返回值是一个函数,函数返回值作为下一个数组项函数的参数。
讲redux之前首先要理解一个函数—–reduce()
语法 array.reduce(function(total, currentValue, currentIndex, arr), initialValue) 参数说明: 一、function(total,currentValue, index,arr) 必需。用于执行每个数组元素的函数。 函数参数: total 必需。初始值, 或者计算结束后的返回值。 currentValue 必需。当前元素 currentIndex 可选。当前元素的索引 arr 可选。当前元素所属的数组对象。 二、initialValue 可选。传递给函数的初始值
reduce()函数有两种用法,一般我们只用到了第一种,即累加(这里不再举例)
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
还有一种比较高级的用法:
reduce() 可以作为一个高阶函数,用于函数的 compose。
注:意思就是写个函数 能将多个函数进行组合成一个函数,就是一元链式函数
注意: reduce() 对于空数组是不会执行回调函数的。
例子:这里想到了数组的reduce()函数
实现思路:要想实现一个这样的函数,肯定是需要有一个遍历的过程,一个函数的执行结果是另一个函数的参数,那这样就需要有个累计的过程,综合以上2点,想到数组中有个reduce函数。这里我们来看看reduce函数
接下来实现:chained函数
function chained(funcs) { return function(input){ return funcs.reduce(function(input, fn){ return fn(input) }, input); } } chained([f3,f2,f1])(2) //调用
函数解析:分为以下4个步骤解析
chained函数入参:funcs 函数数组 返回值:入参为input的函数(这里称为链式回调函数)
链式回调函数:入参:input 初始值 返回值:reduce()函数 funcs 函数数组 执行reduce()函数
reduce函数:入参:计算函数和初始值
计算函数:function(input, fn){ return fn(input) }
首次入参:input输入值 fancs数组的第一个元素 fn1
二次入参:fn1(input)执行后返回值 fancs数组的第一个元素 fn1
…以此类推,知道fancs的数组元素全部参与执行
抽象理解:reduce 英文意思:减少;缩小
A.reduce(function(total, currentValue, currentIndex, arr), initialValue) 可以理解为逐渐减少数组A的元素,减少执行该过程是传给回调函数,用作新的入参,而减少后变为回调函数的另一个入参(即total返回值)
数组A元素变化示意图:元素 ====> 入参 ====>返回值 ====> 入参 ====>……====>最终合成结果
——————————————————————————————————————————————————————
compose函数:
基本语法:compose(fn1,fn2,fn3,fn4,…)
接收参数为函数,函数用逗号隔开,
返回值为:
function(){
fn1(参数) //这里的参数为执行fn2返回的结果
//特别注意:fn2的入参f3的返回结果,依次类推
}
reduce函数执行: reduce第一个入参: function(a, b){ return function(...args){ return a(b(...args)) } } 第一次: a: fn1 b:fn2 第二次:a为上一次的返回值 a: function(){ return fn1(fn2(...args)) //args是f3(...args)的返回结果 } b: fn3 第三次:a为第二次函数返回结果 a: function(){ return fn1(fn2(...args)) }(fn3(...args)) //args是f4(...args)的返回结果 b: f4 第四次:a为第三次函数返回结果 a: function(){ return function(){ return fn1(fn2(...args)) }(fn3(...args)) }(fn4(...args))
函数源码参见:https://github.com/reduxjs/redux/blob/v3.7.2/src/compose.js
export default function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => b(a(...args))) //从左到右 }
将上面的写法转换为es5:
export default function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } //return funcs.reduce((a, b) => (...args) => b(a(...args))) //下面函数是返回的compose函数 return funcs.reduce( //下面返回函数是reduce的回调函数 接收 入参 a, b //a为fn1 ,b为fn2(没有传入初始值) function(a,b){ //下面返回函数是reduce的回调函数实际执行函数 return function(...args){ //这里...args指的是compose函数传入的参数 var transferVal = a(...args) return b(transferVal) } } ) } chained([f3,f2,f1])(2) //调用
执行过程说明:
我们一步一步分解一下, funcs 初始化的值为 funcs = [fn1,fn2,fn3], reduce执行
第一步时
a = fn1
b = fn2
…args = 2
b(a(2)) = fn2(fn1(2))
(2) => b(a(2)) = (2) = > fn2(fn1(2))
第二步时
a = (2) = > fn2(fn1(2)) // 避免和后面混淆,rest参数名修改为 ag
b = fn3
b(a(…args)) = fn3( a(…args) ) = fn3(fn2( fn1(…args) )) // 这一步是关键,a(…args)执行后作为b函数的入参,也就是 …ag = fn3(…args)
(…args) => b(a(…args)) = (…args) = > fn3(fn2(fn1(…args)))
所以最后返回的就是这样的一个函数 (…args) = > fn3(fn2(fn1(…args)))
reduce()合并函数核心:每次的返回值是一个函数,再用该函数去执行下一个数组元素(数组元素先执行传入参数返回)
说明:这里是从左到右
从右到左写为 funcs.reduce((a, b) => (…args) => a(b(…args)))
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/112980.html