This question already has an answer here:
underscore's each checking for {} return of callback
                                
                                    (1个答案)
                                
                        
                                5年前关闭。
            
                    
我刚开始阅读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

最佳答案

仅当对象相同时,===将返回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_.any函数返回假值,我们应该立即退出迭代。这称为短路。但是,理想情况下,each不能短路。为了解决这个问题,他们使用了breaker对象。当iteratoreach函数返回breaker时,each会知道,调用是在内部进行的(因为只有breaker对象可以等于breaker对象,请参见第一个代码。这个答案中的示例),因此必须立即中断。

这就是为什么使用breaker的原因。

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

1. Let expr be the result of evaluating UnaryExpression.
2. Return ToNumber(GetValue(expr)).

09-18 06:22