var any = _.some = _.any = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) {
if (result || (result = predicate.call(context, value, index, list))) return breaker;
});
return !!result;
};
上面是underscore.js中_.any方法的实现。
在下一行测试谓词方法的结果时,
if (result || (result = predicate.call(context, value, index, list)))
result
从一开始就是false
,当result
变量通过调用predicate
函数设置为true时,循环终止。所以在我看来,result
变量的第一次检查将始终评估为false
。为什么对这个变量有额外的测试?
答案 0 :(得分:2)
我在github上发现了一个关于 lshearer
的问题当存在本机forEach函数时,如果使用a调用_.any 列表,其中最后一项未通过真相测试 总是返回false(即使列表中的任何其他项都通过了 真相测试)。问题是本机forEach函数没有 短路(返回断路器;对其没有影响)。因此, 调用_.any的返回结果将被最后一次覆盖 项目
https://github.com/jashkenas/underscore/issues/177
如果查看each
的实现,它会使用原生forEach(如果可用)。
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
}
}
return obj;
};
显然需要额外检查。