Javascript $()。每个vs$。jQuery中每个vs for循环?

Javascript $()。每个vs$。jQuery中每个vs for循环?,javascript,jquery,each,Javascript,Jquery,Each,我不明白为什么会这样 我读到: 第一个$。每个构成一个函数调用来启动 迭代器 第二个$(foo.vals)。每个进行三次函数调用以启动 迭代器 第一个是到$()的,它生成一个新的jQuery包装器 set(不确定在此期间进行了多少其他函数调用 过程) 然后调用$()。每个 最后,它使内部 调用jQuery.each以启动迭代器 在你的例子中,至少可以说差别可以忽略不计。 然而,在嵌套的使用场景中,您可能会发现性能变得越来越重要 一个问题 最后,jQuery启蒙中的Cody Lindley不建

我不明白为什么会这样

我读到:

第一个$。每个构成一个函数调用来启动 迭代器

第二个$(foo.vals)。每个进行三次函数调用以启动 迭代器

  • 第一个是到$()的,它生成一个新的jQuery包装器 set(不确定在此期间进行了多少其他函数调用 过程)
  • 然后调用$()。每个
  • 最后,它使内部 调用jQuery.each以启动迭代器
在你的例子中,至少可以说差别可以忽略不计。 然而,在嵌套的使用场景中,您可能会发现性能变得越来越重要 一个问题

最后,jQuery启蒙中的Cody Lindley不建议使用 $。由于函数调用,每次迭代次数大于1000次 卷入的对(var i=0…循环)使用法线

所以我用这个jsperf测试了它:

(任务:找到选中复选框的Tr,并给Tr上色。)

这是

但是看看

与所有人的期望相反,与之相反的是真实的

使用
$()的人。每个
(调用三个方法)的速度最快
等等

这是怎么回事?

  • $。each()
    是一个正在执行的jQuery函数,用于迭代列表,因此开销应该是jQuery函数以及为列表中的每个项目调用该函数的开销。在这种情况下
  • $(thing).each()
    这背后的思想是,
    $(thing)
    生成一个jQuery实例,然后您迭代这个实例(
    。每个
    作用于该实例)。在您的情况下,因为您调用它的实例已经是一个jQuery对象,所以开销最小(您是实例吗,哦,是的,您是)
  • for()
    在这种情况下,除了在每次迭代中查找列表的长度之外,没有任何开销
考虑做:

var l = g.length;
for (var i=0;i<l;i++) {
    // code;
}
var l=g.length;

对于(var i=0;i您的测试太重,无法真正确定三个循环选项之间的实际差异

如果您想测试循环,那么您需要尽最大努力从测试中删除尽可能多的无关工作

目前,您的测试包括:

  • DOM选择
  • DOM遍历
  • 元素突变
与循环本身相比,所有这些都是非常昂贵的操作。当移除额外的内容时,循环之间的差异更加明显

在Firefox和Chrome中,for
循环比其他循环快100倍以上


处理“任务”的不同方法

但是我想性能问题是因为您没有正确地说明选择器

#t tr input:checkbox:checked 

VS

#t tr :checkbox:checked 
检查复选框是否被选中的正确方法是这样称呼它

#t tr input[checked="checked"]


最后但并非最不重要的是,最快的也是代码最短的那一个,这可能是3行代码与4行和5行代码的性能略有不同,但不能证明这一事实更快。@Stefan你是对的。我一定错过了那个选择器。现在它按预期工作。我同意更长的选择器不一定是最快的,但我不同意它“总是更糟”。来自jQuery API文档:“与其他伪类选择器(以a开头的选择器一样”:”建议在其前面加上标记名或其他选择器;否则,将隐含通用选择器(“”)。换句话说,裸$(':checkbox')等同于$(':checkbox'),因此应改用$('input:checkbox')。”我认为您需要更仔细地决定到底要测试什么。如果您想测试
.each()
$.each()
for
之间的性能差异,那么您需要删除所有其他昂贵的操作,如DOM选择/DOM遍历/元素修改。
$(“\t tr input:checkbox:checked”).closest('tr').css('background-color','red');
!不需要
每个
;)如果我你和他都有工作要做,那么它应该与每一个成比例。这些函数要做多少有什么关系?只要它们都做相同的工作……@RoyiNamir:因为你不再测试循环,而是测试其他所有的东西。我只是说,我所做的工作完全掩盖了循环之间的实际差异已经完成了。如果你不关心循环之间的差异,那么就不要麻烦测试它。如果你关心,那么你需要正确地测试它。再次阅读你的评论。我相信你是对的。我混合了元素选择器引擎,在每个浏览器中可能会有所不同。+1如果你预先计算g.length,循环会更快。啊,一个d当然+1是介绍如何正确测试的答案!为了避免在每次迭代中查找长度(通常在循环持续时间内不会更改),您可以这样做:for(var i=0,len=myArray.length;i