$ .each()vs()循环 – 和性能

这些主要是我一直想知道的一些事情,也许有人可以给我更多的洞察力,我会分享我迄今为止注意到的!

我一直想知道的第一件事是…有没有什么区别好或理由使用:

$('element').each(function (i, el) { });

– 与 –

$.each($('element'), function (i, el) { });

看着jQuery的文档,我看不出任何一个或其他的原因(也许你知道一个实例或另一个可以做的事情比另一个。

但更重要的是我关心速度

 // As opposed to $.each() looping through a jQuery object // -- 8x faster for (var i = 0, $('.whatever').length; i < len; i++) { $('.whatever')[i] // do stuff } 

如果你在这里查看这个jsFiddle DEMO ,你会发现速度的差异基本上与它们中的任何一个相当,但是更重要的是我觉得应该总是使用for()循环。

我只是unit testing(遍历5个不同场景函数的每一个,5万次),简单地遍历一堆列表项,并设置一个data-newAttr ,没有什么特别的。


问题:我想我最大的问题是,为什么不在迭代通过对象时总是使用循环? 甚至有点使用$ .each()? 即使在通过jQuery对象时,你总是使用for()循环吗?

这里的jsFiddle DEMO

 Function type: Execution Time: _testArea.each() + $(this) 1947 <-- using $(this) slows it down tremendously $.each() + $(this) 1940 _testArea.each() + el(plain JS) 458 <-- using the Element speeds things up $.each() + el(plain JS) 452 for() loop + plainJS[0] iteration 236 <-- over 8x faster 

只是我的2cents。 🙂

有一件事.each()允许你这样做,不能用for循环做链接

 $('.rows').each(function(i, el) { // do something with ALL the rows }).filter('.even').each(function(i, el) { // do something with the even rows }); 

我玩弄了你的JSFiddle ,看看链接如何影响性能的情况下,你必须循环通过原始的一组匹配元素的子集。

结果并不是所有这些意外,但我认为end()的开销在这里被夸大了,因为less数元素和很多循环的结合。 除此之外:普通的JS循环仍然稍微快一点,但是是否会影响到.each() (和链接)的附加可读性是值得商榷的。

你使用.each()所做的一件事就是自动本地范围确定(因为你为每个对象调用一个匿名函数),这意味着如果你在每次迭代中创build更多的匿名函数/闭包/事件处理器/你永远不用担心你的处理程序共享一个variables。 也就是说,当涉及到本地范围时,JavaScript并不像其他语言那样行事,但是由于您可以在任何地方声明一个variables,它有时可能会欺骗您。

换句话说,这是错误的:

 var idx,el; for (idx = 0; idx <someObjectArray.length; idx++){ el = someObjectArray[idx] el.someEventHandler(function(){ alert( "this is element " + idx); }); } 

每当这些对象在这个循环之后调用它们的“someEvent”(请注意,这是由这个组成的),警报总是会说上次分配给idx任何东西,应该是(从调用的时间开始) someObjectArray.length ;

为了确保保存正确的索引,必须声明一个本地作用域,创build一个variables并分配给该variables以供使用。

 var idx,el; for (idx = 0; idx <someObjectArray.length; idx++){ el = someObjectArray[idx]; (function(){ var localidx = idx; el.someEventHandler(function(){ alert( "this is element " + localidx); }); })(); } 

正如你所看到的,这就像地狱一样丑陋,但它应该工作。 每个事件处理程序都获得它自己的localidx副本

现在比较一下.each()

 $(someObjectArray).each(function (idx, el) { el.someEventHandler(function(){ alert( "this is element " + idx); }); }); 

简单得多,不是吗?

jQuery.each与for循环

好处jQuery.each:

  • 适合jQuery代码(链接和样式)。
  • 不用担心范围(对迭代器和对象的引用将是持久的)。
  • 可以普遍使用(用于各种对象并遍历对象键)。

for-loop的优点:

  • 高性能(游戏/animation/大型数据集)。
  • 完全控制迭代器(跳过项目,从列表拼接项目等)。
  • for循环将始终工作,因为不依赖于jQuery。
  • 与大多数其他类似语言一样熟悉的语法。

示例代码

这是我更喜欢迭代列表的示例代码。

 var list = ['a', 'b', 'c', 'd', 'e', 'f']; 

jQuery.each:

 $.each(list, function(i, v) { // code... }); 

没有closures的循环:

 for(var i=0,v,n=list.length;i<n;i+=1) { v = list[i]; // code... } 

闭环闭环:

 for(var i=0,n=list.length;i<n;i+=1) { (function(i, v) { // code... })(i, list[i]); } 

注意:我build议你只使用标准的for-loop,并且只在必要的时候使用闭包。 然而,无论如何,当你的代码看起来比jQuery更像jQuery时,使用$.each可能会更容易$.each 如果出现性能问题,可以随时查看。

当我去你的链接这里有两个数字,我得到了:

 $.each() + el(plain JS) 401 for() loop + plainJS[0] iteration 377 

如果差距很小,那就select一个最具可读性的区域,但是如果时间要求非常高的话,那么你可能只需要以最快的速度进行。

我build议你编写你的程序,使用三种不同的方法,上面的两个,然后使用新版本的JavaScript中find的foreach,对于那些不支持它的浏览器,你可以添加它作为原型。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach

你知道你的要求是什么,你的程序会做什么,所以只需编写你自己的testing,并确保它符合你将要支持的浏览器的要求。

对于你的第一个问题,我会去$('element').each因为它更容易阅读,但这只是我的看法。

我之前运行了一些简单的性能testinghttp://jsperf.com/forloops3 。 似乎坚持平原,旧for loop (这是可能的)是要走的路:)

实际上$ .each()和$()。each()之间有很大的区别。

他们根据你传递的内容做些微不同的事情。

http://api.jquery.com/each/ vs http://api.jquery.com/jquery.each/

jquery.each是一个通用的迭代器,其中$()。each()是特定于jquery集合的。

另见: http : //jsperf.com/each-vs-each-vs-for-in/9