在下划线的最新代码here中,在第211行读取
result || (result = iterator.call(context, value, index, list))) return breaker;
是需要的还是声明?可以用
代替(result = iterator.call(context, value, index, list))) return breaker; // ?
result
最初设置为false,除了这一行之外,代码中没有其他地方被修改。
请注意,JavaScript或(||)语句返回第一个操作数(如果它是真实的),第二个操作数(如果它'是第一个操作数)是假的。这是直接来自Crockford,Good Parts。还注意到||做一个或与truthy / falsy值不是真/假值。
以下是从上面链接转载的整个方法:
var any = _.some = _.any = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
答案 0 :(得分:7)
这让我觉得result||
检查只是为了以防万一...或支持定义forEach
的环境(例如通过垫片),但some
不是。< / p>
正如评论中所指出的,由于以下几个原因,下划线依赖本机循环方法(forEach
,map
和朋友)似乎并不是一个好主意:
Array.prototype
可被其他(恶意或愚蠢)代码篡改答案 1 :(得分:3)
答案是:是,可以按建议的方式进行优化如果是原生代码。
为了理解将会发生什么,让我们将代码简化为重要的事项,首先:
var result = false;
for (var i in obj)
{
if (result || (result = call(i)))
return;
}
这意味着,如果result
已经非假,它将返回,或者如果call()
返回非假值,它将返回。由于结果仅由call()
更改,因此对result
的首次检查是多余的。
var result = false;
for (var i in obj)
{
if (result = call(i))
return;
}
只要call()
传递了非假值,此代码仍会返回。
此外,each()
是一个库函数,OP在找到的项目上返回breaker
真正发生的是:
var result = false;
for (var i in obj)
{
if (result || (result = call(i)))
break;
}
在这种情况下,只要使用了librarys foreach函数,代码仍然可以以建议的方式进行优化。循环将保留在找到的值上。
令人困惑的部分是each()
是一个库函数,它使用一个函数来模拟循环体。从body函数返回库常量breaker
将退出循环。
只要each()
决定使用原生.forEach()
,代码就无法优化,因为.forEach()
无法理解breaker
的返回值1}}!有关详细信息,请参阅 thg435 的答案!