这些主要是我一直想知道的一些事情,也许有人可以给我更多的洞察力,我会分享我迄今为止所注意到的内容!
我一直在想的第一件事......使用是否有任何不同之处:
$('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 here ,您会发现速度上的差异与其中任何一个基本相同,但更重要的是我觉得我应该始终< / em>使用for()
循环......
我只是单元测试(循环遍历5个不同的场景函数,50,000次),只是循环遍历一堆列表项,并设置data-newAttr
,没什么特别的。
问题::我想我最大的问题是,为什么总是在迭代对象时使用for循环?是否有使用$ .each()的意义?即使在浏览jQuery对象时,你总是使用for()循环吗?
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。 :)
答案 0 :(得分:43)
使用.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
});
I played around with your JSFiddle了解在必须循环遍历原始匹配元素集的子集的情况下,链接如何影响性能。
结果并非一切都出乎意料,尽管我认为end()
的开销在这里被夸大了,因为少数元素和许多循环的组合。除此之外:普通的JS循环仍然稍微快一些,但是否能够增加.each()
(和链接)的可读性是值得商榷的。
答案 1 :(得分:21)
使用.each()
得到的一件事是自动本地作用域(因为你正在为每个对象调用一个匿名函数),这反过来意味着你是否正在创建更多的匿名函数/闭包/事件处理程序/无论如何在每次迭代中,您都不必担心处理程序共享变量。也就是说,当涉及本地范围时,JavaScript不像其他语言那样,但是因为你可以在任何地方声明变量,它有时会欺骗你。
换句话说,这是错误的:
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
;
要确保保存正确的索引,您必须声明一个本地范围,创建一个变量并分配给该变量以供使用。
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);
});
});
更简单,不是吗?
答案 2 :(得分:9)
优点jQuery.each:
for-loop的优点:
这是我更喜欢迭代列表的示例代码。
var list = ['a', 'b', 'c', 'd', 'e', 'f'];
jQuery.each:
$.each(list, function(i, v)
{
// code...
});
没有关闭的For循环:
for(var i=0,v,n=list.length;i<n;i+=1)
{
v = list[i];
// code...
}
带闭包的For循环:
for(var i=0,n=list.length;i<n;i+=1)
{
(function(i, v)
{
// code...
})(i, list[i]);
}
注意:我建议您只使用标准for循环,并在必要时仅使用闭包。但是,当您的代码看起来更像jQuery而不是Javascript时,使用$.each
可能更容易。如果出现性能问题,您可以随时查看。
答案 3 :(得分:5)
我在前http://jsperf.com/forloops3时进行了一些简单的性能测试。似乎坚持简单,旧的for loop
(可能的地方)是要走的路:)
答案 4 :(得分:4)
当我找到你的链接时,我得到了两个号码:
$.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
因为它更容易阅读,但这只是我的意见。
答案 5 :(得分:1)
实际上$ .each()和$()。each()之间存在很大差异。
根据您传入的内容,它们会略有不同。
http://api.jquery.com/each/ vs http://api.jquery.com/jquery.each/
jquery.each是一个通用迭代器,其中$()。each()特定于jquery集合。