38

我不明白为什么会这样。

我在这里读到:

第一个$.each构成了启动迭代器的单个函数调用。

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

  • 第一个是 $() ,它产生一个新的 jQuery 包装器集(不确定在此过程中进行了多少其他函数调用)。
  • 然后调用 $().each。
  • 最后,它对 jQuery.each 进行内部调用以启动迭代器。

在您的示例中,至少可以说差异可以忽略不计。但是,在嵌套使用场景中,您可能会发现性能成为一个问题。

最后,jQuery Enlightenment 中的 Cody Lindley 不建议将 $.each 用于大于 1000 的迭代,因为涉及到函数调用。使用普通的 for( var i = 0... 循环。

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

(任务:找到选中复选框的Tr,并为该tr着色。)

这是jsbin

但是看看jsperf

出乎所有人的意料,事实恰恰相反。(铬和FF和IE)

在此处输入图像描述

使用$().each( 调用三种方法的人是最快的等等..

这里发生了什么?

4

3 回答 3

38

您的测试太重,无法真正确定三个循环选项之间的实际差异。

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

就目前而言,您的测试包括:

  • DOM 选择
  • DOM 遍历
  • 元素突变

与循环本身相比,所有这些都是相当昂贵的操作。删除多余的东西时,循环之间的差异更加明显。

http://jsperf.com/asdasda223/4

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

在此处输入图像描述

于 2013-02-11T08:56:03.820 回答
3

  • $.each()是一个正在执行的 jQuery 函数,它将用于迭代您的列表,因此开销应该是 jQuery 函数以及为列表中的每个项目调用该函数的开销。在这种情况下
  • $(thing).each()这背后的想法是$(thing)创建一个 jQuery 实例,然后迭代这个实例(.each作用于那个实例)。在你的情况下,因为你调用它的实例已经是一个 jQuery 对象,所以开销是最小的(你是一个实例,哦,是的,你是)。
  • for()在这种情况下,根本没有开销,除了在每次迭代中查找列表的长度。

考虑做:

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

根据您的 HTML,大部分时间很可能在 Sizzle Jquery 解析器中找到文档中的选择器。

另请注意,我认为您的选择器不是最好的,除非最近情况发生了重大变化 jQuery 选择器是从右到左评估的,考虑通过.find()对 id 引用的第一个标签下的所有内容执行 a 来限制选择器的范围,因为它会然后只搜索文档的一个子集。

于 2013-02-11T08:40:03.013 回答
0

您的“任务”的不同方法http://jsfiddle.net/ADMnj/17/

但我想性能问题来自于你没有在正确的问题上声明选择器

#t tr input:checkbox:checked 

VS

#t tr :checkbox:checked 

检查复选框是否被选中的正确方法是这样调用它

#t tr input[checked="checked"]

W3.ORG 的选择器列表见 E[foo]

最后但并非最不重要的一点也是最快的也是代码最短的代码,这可能是您从 3 行代码与 4 行和 5 行代码获得的性能略有不同,但无法证明这一事实

于 2013-02-11T09:24:52.963 回答