$. each() vs for()循环-和性能

这些主要是一些事情,我一直想知道,也许有人可以给我一些更多的见解,我会分享我注意到到目前为止!

我一直在想的第一件事... 有没有什么不同的好处或者理由来使用:

$('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()循环..。

我只是单元测试(在5个不同的场景函数中循环5万次) ,只是在一堆列表项中循环,然后设置一个 data-newAttr,没有什么特别的。


问: 我想我最大的问题是,为什么 一直都是在迭代一个对象时不使用 for 循环? ?使用 $。每个人?即使在遍历 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

只是我的两分钱。 :)

75268 次浏览

.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()的开销在这里被夸大了,因为它结合了很少的元素和很多的循环。除此之外: 普通的 JS 循环仍然稍微快一些,但是这是否会增加 .each()(和链接)的可读性是有争议的。

当我打开你的链接时,我得到了两个号码:

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

如果差异很小,那么选择可读性最强的那个,但是,如果你有很高的时间要求,那么你可能只需要选择最快的那个。

我建议您使用三种不同的方法来编写程序,上面两种,然后使用在新版本的 javascript 中找到的 foreach,对于那些不支持它的浏览器,您可以将它作为原型添加进来。

Https://developer.mozilla.org/en-us/docs/javascript/reference/global_objects/array/foreach

您知道您的需求是什么,以及您的程序将做什么,所以只需编写您自己的测试,并确保它满足您将要支持的浏览器的需求。

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

使用 .each()可以获得自动局部作用域(因为您为每个对象调用了一个匿名函数) ,这反过来意味着如果您在每次迭代中创建更多的匿名函数/闭包/事件处理程序/无论什么,您都不必担心处理程序共享一个变量。也就是说,当涉及到本地作用域时,JavaScript 的行为与其他语言不同,但是因为您可以在任何地方声明变量,所以它有时会欺骗您。

换句话说,这是错误的:

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

每当这些对象中的任何一个在这个循环之后调用它们的“ some Event”(请注意这是编造的) ,警报总是会说上次分配给 idx的内容,它应该是(在调用时) someObjectArray.length;

为了确保保存正确的索引,您必须声明一个局部范围,创建一个变量并赋值给该变量以供使用。

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

简单多了,不是吗?

http://jsperf.com/forloops3之前,我运行了一些简单的性能测试。似乎坚持简单、老式的 for loop(在可能的情况下)才是正确的选择:)

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

根据你要传递的内容,它们的作用略有不同。

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

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

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

Each vs for-loop

优点 jQuery. each:

  • 非常适合 jQuery 代码(链接和样式)。
  • 不用担心范围(对迭代器和对象的引用将是持久的)。
  • 可以普遍使用(对于所有类型的对象和迭代对象键)。

For-loop 的优点:

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

示例代码

这是我喜欢如何在列表上迭代的示例代码。

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

JQuery. each:

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

没有闭包的 For-loop:

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

带闭包的 For-loop:

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

注意: 我建议您只使用标准的 for-loop,并且只在必要时使用闭包。但是,如果代码看起来更像 jQuery 而不是 Javascript,那么使用 $.each会更容易。如果出现性能问题,您总是可以在以后进行调查。