终于看完了 Underscore 的集合部分了,看 Underscore 源码真的是长见识了,感觉真的受益匪浅。
但是集合里面方法也挺多的,我都不知道该拿哪些出来讲下,最近接触了 Redux,就说下 createRedux 这个方法吧,为后面讲 Redux 做个铺垫。
先看源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| var createReduce = function(dir) { var reducer = function(obj, iteratee, memo, initial) { var keys = !isArrayLike(obj) && _.keys(obj), length = (keys || obj).length, index = dir > 0 ? 0 : length - 1; if(!initial) { memo = obj[keys ? keys[index] : index]; index += dir; } for(; index >= 0 && index < length; index += dir) { var currentKey = keys ? keys[index] : index; memo = iteratee(memo, obj[currentKey], currentKey, obj); } return memo; }; return function(obj, iteratee, memo, context) { var initial = arguments.length >= 3; return reducer(obj, opitimizeCb(iteratee, context, 4), memo, initial); }; };
|
这是 reduce 函数的工厂函数,用于生成一个 reducer ,dir 是决定方向用的。
我们从最后一个 return 开始看起,即
1 2 3 4
| return function(obj, iteratee, memo, context) { var initial = arguments.length >= 3; return reducer(obj, opitimizeCb(iteratee, context, 4), memo, initial); };
|
我们使用 reduce 的时候,如果没有指定 memo 值,这时候参数个数只有两个即 obj 和 iteratee,所以 initial 为 false 表示没有初始化。对于没初始的情况,就是增加了一个 if 语句里面的内容而已,作用是把第一个元素作为 memo 值。
接着就是有没有初始化都共用的部分了,通过一个 for 循环把 keys 遍历,并把相应的信息交给 iteratee 去处理,参数 memo 是上一次处理结果。遍历完后把最后的处理结果 memo 返回就完了。
这个函数派生了两个方法,即
1 2
| _.reduce = _.foldl = _.inject = createReduce(1); _.reduceRight = _.foldr = createReduce(-1);
|
只是方向不同而已。
举个例子方便理解些,例如:
1 2 3
| var sum = _.reduce([1, 2, 3, 4, 5], function(accumulator, value, index, collection) { return accmulator + value; }, 0);
|
结果为 15 这个应该很明显,js 原生也有 reduce 方法,如下:
1 2 3
| [1, 2, 3, 4, 5].reduce(function(left, right) { return left + right; });
|
我们看下 Underscore 的例子,主要想说明下他的运行过程,如下:
1 2 3 4 5 6 7 8 9 10
| if(!initial) memo = 1; index = 1; endif for memo = iteratee(1, 2, 1, [1, 2, 3, 4, 5]) = 3; memo = iteratee(3, 3, 2, [1, 2, 3, 4, 5]) = 6; memo = iteratee(6, 4, 3, [1, 2, 3, 4, 5]) = 10; memo = iteratee(10, 5, 4, [1, 2, 3, 4, 5]) = 15; endfor return memo = 15;
|
额,我也不知道写的是什么东西,只是描述下过程而已,你懂的。
剩下的集合部分感觉也没啥好说的了,花点时间看下就可以看懂了=.=。