为什么下划线使用object作为断路器

时间:2014-03-22 16:07:04

标签: javascript underscore.js

我刚开始阅读underscore annotated source code,我发现他们使用Object literal {}作为breaker这样:

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

if语句中+用于从string转换为number以及字符串连接,以及常规算术运算。

我试过了:

console.log(+"5");//=>5
console.log(+5);//=>5
console.log(5===+5);//=>true

1 个答案:

答案 0 :(得分:2)

仅当对象相同时,

===才会返回true。看看这个

console.log({} === {});
# false

underscore.js使用了这个事实。 breaker实际上是一个哨兵值。让我们采用您在问题_.each中引用的功能。第二个参数(iterator)是一个函数。如果您查看_.all_.any函数,他们会执行类似这样的操作

<强> _。所有

each(obj, function(value, index, list) {
  if (!(result = result && predicate.call(context, value, index, list))) return breaker;
});

<强> _。任何

each(obj, function(value, index, list) {
  if (result || (result = predicate.call(context, value, index, list))) return breaker;
});

他们都使用each函数,这是您在问题中提到的检查所在的位置。如果传递给predicate_.all的{​​{1}}函数返回一个假值,我们应该立即突破迭代。这称为短路。但是,理想情况下_.any不能短路。为了克服这个问题,他们使用了each个对象。当breaker iterator函数返回each时,breaker会知道,调用是在内部进行的(因为只有each对象可以等于breaker对象,请参阅此答案中的第一个代码示例),因此必须立即中断。

这就是使用breaker的原因。

关于问题的第二部分,一元breaker运算符旨在将表达式转换为数字。引自ECMA 5.1 Specification for the Unary + operator

+