在读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
原生的reduce方法是Array的原型对象中带的方式,对于类数组对象不适用
例如
需要通过如下才可以:
同样不支持对普通对象的属性的遍历reduce操作
而underscore提供对类数据对象和普通对象属性的遍历reduce操作