jQuery 选择器性能问题

标签 jquery performance jquery-selectors

我有 3 个关于选择器性能的疑问:

首先,以下语句是否存在性能差异:

$('#content .someclass')$('.someclass', '#content')

我一直使用第一种方式,但最近似乎有更多的人转向第二种方式。两者之间有什么好处

其次,如果我添加 div.someclass,会比仅仅 .someclass 更好(如果 someclass 的所有元素无论如何都将是 div)。我本以为在这种情况下第一个会慢一些,因为它必须首先获取所有 div,然后是带有 .someclass 的 div,但由于我不确定选择器如何工作,所以我只是猜测

最后,如果我使用 $(this),缓存这个对象会更好吗 - var $thisobject = $(this) 还是没有区别?我一直认为 $(this) 本身就是一个 jQuery 对象,但我现在认为它实际上是将 this 转换为 jQuery 对象,因此也许将其粘贴到变量比调用多个 $(this)

更好

最佳答案

除了您列出的两个选择之外,还有第三个选择:

1: $('#content .someclass')

2: $('.someclass', '#content')

3: $('#content').find('.someclass')

有一件事我们可以在不运行任何测试的情况下肯定地说:#3 比 #2 更快。那是因为#2 在内部变成了#3。这是jQuery source code就是这样做的。它位于 init() 函数中,它实际上是 jQuery 构造函数。经过一系列相当长的测试后,它检测到您已调用 $(selector,context) 并进行 $(context).find(selector) 调用:

// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
    return this.constructor( context ).find( selector );
}

您可以让 $(context).find(selector) 自己调用并避免额外的检查。

所以 #2 从来都不是最快的代码; #3 永远会打败它。

正如 @KevinB 指出的,#2 是 not a documented use $/jQuery 函数的。这可能只是文档中的一个疏忽,因为它是对#3 的直接转换,#3 是该函数的记录使用,并且代码多年来一直以这种方式工作。

无论如何,即使在已记录的情况下,也几乎没有任何理由使用 #2,因为 #3 更快且更容易理解。

#3 与#1 相比如何?在大多数情况下可能会更快,但它可能会因浏览器以及特定选择器和页面复杂性而异。 jsPerf是你的 friend ,但一定要给它一个与重要页面类似的页面,而不仅仅是一个人为的测试。

div.someclass 与 .someclass 的情况相同。测试一下看看。

关于 $(this)$ 函数名称有时会让事情看起来很神奇,因为它们只是普通的 JavaScript 函数调用。为了便于理解,请尝试使用 jQuery 函数名称:

jQuery(this)

现在应该更清楚了,这确实是一个函数调用,而不是某种神奇的语法。当您使用 $(this)$(anything) 时,情况是一样的:它始终是函数调用。所以是的,如果您重复使用它,最好将结果保存在变量中:

var $this = $(this);

我唯一的建议是不要命名变量$thisobject。额外的 object 措辞并没有真正让这个名字变得更清晰;简单的 $this 对于其他开发人员来说会更熟悉。或者最好使用更具描述性的名称,例如

var $element = $(this);

一般来说,this$this 在 jQuery 代码中被严重过度使用,最好尽可能使用具有简短但描述性名称的普通变量。

考虑这个人为设计的 jQuery 插件:

jQuery.fn.log = function() {
    this.each( function() {
        console.log( this );
    });
    return this;
};

在这个简短的函数中,this 的含义发生了两次变化:首先它是 jQuery 对象,然后它是该对象的单个元素,然后它再次是 jQuery 对象。难怪人们对这个有困难!

相反,您可以使用 .each() 的命名参数:

$.fn.log = function() {
    this.each( function( i, element ) {
        console.log( element );
    });
    return this;
};

这就不那么令人困惑了,如果您需要在内部函数中为 element 使用 jQuery 对象,您可以像使用 this 一样进行操作:

var $element = $(element);

关于jQuery 选择器性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16922228/

相关文章:

python - CPU 和 GPU 生成的结果不匹配

javascript - 如何使用 jQuery .next() 选择下 2 个(或 2 个以上)项目?

javascript - 使用 javascript 分割字符串

jquery - 动态分配 'active' 类

jquery - 使用 JQuery 的 Accordion 在 Internet Explorer 9 中不显示图像

c++ - 中型对象连接和合并的 vector

jquery - 使用 "overflow: scroll"时,翻页卡背面的内容在 Chrome 中显示在前面,而不是其他浏览器

asp.net - 分析 ASP.NET Web 应用程序的 CPU 使用率 - 但不是数据库!

javascript - jQuery - 在表中的 <tr> 元素上单击事件并获取 <td> 元素值

jquery - 当我们关闭叠加层时,YouTube 视频不会停止