我有3个关于选择器性能的查询:
首先,以下陈述中是否存在任何性能差异:
$('#content .someclass')
和$('.someclass', '#content')
我一直使用第一种方式,但最近更多的人似乎正在转向第二种方式。这两个之间有什么好处
其次,如果我添加div.someclass
,那会比仅仅.someclass
更好(如果某些类的所有元素都将成为div)。我本以为在这种情况下第一个会慢一些,因为它必须首先得到所有的div然后是.someclass
的那个但是因为我不确定选择器是如何工作的我只是猜测
最后,如果我使用$(this)
,最好是缓存此对象 - var $thisobject = $(this)
还是没有区别?我一直认为$(this)
本身就是一个jQuery对象,但我现在认为它实际上是将this
转换为jQuery对象,所以将它粘贴到变量中会比调用多个{{}更好。 1}}
答案 0 :(得分:1)
这取决于选择器的确切性质。
在 general 中,最好让浏览器完成所有繁重的工作,因为它可以直接访问DOM,因此您可能会认为前者更快。
AIUI,浏览器通常在选择器中从“从右到左”工作,因此它会找到所有具有类.someclass
和然后的元素将结果过滤为{的后代。 {1}}。
在这种特定情况下,“父”由ID标识,因此可以更快地告诉浏览器从该特定元素开始并且仅考虑其后代。
换句话说,“它取决于”。尝试在真实页面上,或在jsperf.com上,看看会发生什么。
答案 1 :(得分:1)
除了您列出的两个选项之外,还有第三个选择:
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是$
/ jQuery
函数的not a documented use。这可能只是对文档的疏忽,因为它是对#3的直接转换,它是函数的文档化使用,并且代码已经以这种方式工作多年。
在任何情况下,即使在其记录的案例中也几乎没有理由使用#2,因为#3更快更容易理解。
#3与#1相比如何?在大多数情况下可能更快,但它可能因浏览器之间以及特定选择器和页面复杂性而异。 jsPerf在这里是你的朋友,但一定要给它一个类似于重要的页面,而不仅仅是一个人为的测试。
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对象。难怪人们遇到this
的问题!
相反,您可以将命名参数用于.each()
:
$.fn.log = function() {
this.each( function( i, element ) {
console.log( element );
});
return this;
};
这更不容易混淆,如果你需要在内部函数中使用element
的jQuery对象,你可以像this
一样使用它:
var $element = $(element);
答案 2 :(得分:1)
未提及的是浏览器之间存在差异。在不支持querySelectorAll
的浏览器中,策略会发生变化。例如,如果浏览器确实支持该方法,那么类似$('#id').find(' > li > a')
的东西可能会非常快......在没有的浏览器上(遗留的IE,最值得注意的是),你可能会更喜欢类似的东西$('#id').children('li').children('a')
。