【问题标题】:$().each vs $.each vs for loop in jQuery?$().each vs $.each vs for jQuery中的循环?
【发布时间】:2013-01-26 07:39:02
【问题描述】:

我不明白为什么会这样。

我读到here

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

第二个 $(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的那个(调用三个方法最快 等等。

这是怎么回事?

【问题讨论】:

  • #t tr input:checkbox:checked#t tr :checkbox:checked 是两个不同的选择器,我认为第一个更快。
  • @Stefan 你是对的。我一定错过了那个选择器。现在它按预期工作。
  • 我同意较长的选择器不一定是最快的,但我不同意它会“总是更糟”。来自 jQuery API 文档:“与其他伪类选择器(以“:”开头的那些)一样,建议在其前面加上标签名称或其他选择器;否则,通用选择器(“” ) 是隐含的。换句话说,裸露的 $(':checkbox') 等价于 $(':checkbox'),所以应该使用 $('input:checkbox') 来代替。 api.jquery.com/checkbox-selector
  • 我认为你需要更仔细地决定你究竟想要测试什么。如果要测试.each()$.each()for之间的性能差异,则需要删除所有其他昂贵的操作,例如DOM选择/DOM遍历/元素修改。
  • $('#t tr input:checkbox:checked').closest('tr').css('background-color', 'red');!不需要each ;)

标签: javascript jquery each


【解决方案1】:

  • $.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 解析器中找到文档中的选择器。

另外请注意,我不认为您的选择器是最好的,除非最近情况发生了重大变化由 id 引用,因为它将只搜索文档的一个子集。

【讨论】:

  • 为了避免在每次迭代时查找长度(通常在循环期间不会改变),您可以这样做: for (var i=0,len=myArray.length; i
【解决方案2】:

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

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

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

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

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

http://jsperf.com/asdasda223/4

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

【讨论】:

  • 如果我你和他都有工作要做,那么它应该与每个工作成正比。这些功能有多少有什么关系?只要他们都做同样的事情......
  • @RoyiNamir:因为您不再测试循环,而是测试其他所有内容。我只是说循环之间的实际差异完全被正在完成的工作所掩盖。如果您不关心循环之间的差异,那么就不要费心测试它。如果你这样做了,那么你需要正确地测试它。
  • 再次阅读您的评论。我相信你是对的。我混合了在每个浏览器中可能不同的元素选择器引擎。 +1
  • 如果你预先计算 g.length 循环会更快。
  • 啊,当然还有 +1 用于介绍如何正确测试的答案!
【解决方案3】:

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

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

#t tr input:checkbox:checked 

VS

#t tr :checkbox:checked 

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

#t tr input[checked="checked"]

W3.ORG's selector list see the E[foo]

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

【讨论】:

    猜你喜欢
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    相关资源
    最近更新 更多