Javascript 需要这个或(| |)声明吗?
在下划线的最新代码中,第211行Javascript 需要这个或(| |)声明吗?,javascript,underscore.js,Javascript,Underscore.js,在下划线的最新代码中,第211行 result || (result = iterator.call(context, value, index, list))) return breaker; 是否需要or声明?是否可以用 (result = iterator.call(context, value, index, list))) return breaker; // ? result最初设置为false,并且除了这一行之外,代码中没有其他地方需要修改 请注意,JavaScript或(|
result || (result = iterator.call(context, value, index, list))) return breaker;
是否需要or声明?是否可以用
(result = iterator.call(context, value, index, list))) return breaker; // ?
result
最初设置为false,并且除了这一行之外,代码中没有其他地方需要修改
请注意,JavaScript或(| |)语句如果第一个操作数为truthy,则返回第一个操作数;如果第二个操作数('it'为第一个操作数)为falsy,则返回第二个操作数。这是直接从Crockford,好的部分。还注意到| |使用真/假值的or不是真/假值
以下是从上述链接复制的整个方法:
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;
};
答案是:是,如果它是本机代码,则可以按照建议的方式对其进行优化 为了理解将要发生的事情,让我们将代码简化为此处的重点,首先:
var result = false;
for (var i in obj)
{
if (result || (result = call(i)))
return;
}
这意味着,如果result
已为非false,则返回;如果call()
返回非false值,则返回。由于结果仅由call()
更改,因此对result
的第一次检查是多余的
var result = false;
for (var i in obj)
{
if (result = call(i))
return;
}
只要call()
传递了一个非false值,此代码仍将返回
这也是因为each()
是一个库函数,OP在找到的项上返回breaker
真正发生的是:
var result = false;
for (var i in obj)
{
if (result || (result = call(i)))
break;
}
在这种情况下,只要使用Library的foreach函数,代码仍然可以按照建议的方式进行优化。找到一个值后,将留下循环
令人困惑的是,each()
是一个库函数,它使用一个函数来模拟循环体。从body函数返回库常量breaker
,将退出循环
一旦
each()
决定使用本机.forEach()
就无法再优化代码,因为.forEach()
将无法理解断路器的返回值!详见thg435的答案 这让我觉得结果|
检查只是以防万一。。。或者支持定义了forEach
(例如通过垫片)但部分未定义的环境
正如评论中所指出的,下划线依赖本机循环方法(forEach
、map
和friends)似乎不是一个好主意,原因如下:
- 它们不仅仅是简单的循环
- 您不能中断(当然,您可以使用专用的异常,但下划线不能这样做)
Array.prototype
可以被其他(恶意或愚蠢的)代码篡改
可能是为了性能?包含if的函数会多次运行,并在相同的结果值上工作。第一次它肯定是错误的。最初的结果是错误的,但可以在每次迭代中更改。此代码假定结果只更改一次。如果没有| |迭代器,每次迭代都会执行迭代器.call。@NicoSantangelo如果性能是一个问题,那么这个函数中已经有太多严重的错误了,对性能进行这样的欺骗是荒谬的。@Ian只是澄清一下,result
只需要是一个假值,而不一定是false
哦!我从没想过!什么时候每个都不是方法?我想我应该看看文档/代码这超出了我的理解范围,很容易让自定义的每一个执行速度都比内置的快一个数量级,但是下划线会回到原生的,它不仅慢得多,而且语义也明显不同。耶稣基督,为什么?看看网络的情况。这意味着如果存在本机forEach
,则使用它。当这种情况发生时,返回断路器将不会停止任何操作。答案是correct@thg435这并不是绝对可以保证的,因为从技术上讲,没有任何东西可以阻止一个人删除。一些,并保留。forEach
。@Esailija:在帖子中添加了一些下划线攻击;)但是,根据,返回breaker
意味着每个
函数将停止迭代。@matehat谢谢!没有注意到OPs代码中的垂直滚动条将被编辑。