在读underscore
的源码,有一个疑问,为什么不优先选择原生的reduce
和reduceRight
源码中,比如 _.keys
,都是先探测是否支持Object.keys
的。
// Create a reducing function iterating left or right. // ? why dont use native reduce var createReduce = function(dir) { // Wrap code that reassigns argument variables in a separate function than // the one that accesses `arguments.length` to avoid a perf hit. (#1991) 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, optimizeCb(iteratee, context, 4), memo, initial); }; };// **Reduce** builds up a single result from a list of values, aka `inject`,// or `foldl`._.reduce = _.foldl = _.inject = createReduce(1);// The right-associative version of reduce, also known as `foldr`._.reduceRight = _.foldr = createReduce(-1);
解决方案
原生的 reduce 只用于数组,underscore 的 reduce 能用于 Object
顺带安利我的 Repo -> https://github.com/hanzichi/underscore-analysis