为什么在条件允许的情况下需要额外检查?

时间:2014-02-21 06:55:35

标签: javascript underscore.js

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。为什么对这个变量有额外的测试?

1 个答案:

答案 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;
};

显然需要额外检查。