我开始为我正在进行的项目优化我的一些脚本,一个好的起点似乎是jQuery构造函数本身。
在我的脑海中,我想到了构建/传递jQuery对象的几种不同方法。然后我用以下案例制作了一个JSPerf并得到了令人难以置信的意外结果:
$("#inner").html(); // Fastest (1)
var x = $("#inner"); // (2)
x.html();
var x = $("#inner"); // (3) !!!
$("#inner").html();
var x = $("#inner"); // Slowest (4) !!!
$(x).html();
在案例3和案例4中,重新执行查询并从结果构造jQuery实际上比从已构造的jQuery对象返回jQuery对象更快。我原以为jQuery只返回对象,如果它可用,但这显然不可能是真的,因为在案例3和4之间存在~100k ops / sec的差异。
实际在这里发生了什么?有没有一个原因jQuery不只是返回一个已经构造的对象(例如:也许它"刷新"一个jQuery对象来匹配DOM)?或者,我的测试是否偏向于案例4,这些结果是什么意思?我预计案例3是最慢的,因为它执行了两次查询,但为什么不是呢?
答案 0 :(得分:2)
看看未压缩的生产版本(这里是1.11.x分支的副本): 你填写找到jquery构造函数为
init = jQuery.fn.init = function( selector, context ) {
// ...
}
那么为什么你的一个例子比另一个慢呢? 看一下构造函数中的if / else结构,并且(在性能测试中给出了数百万次迭代),您可以安全地假设执行时间将根据所采用的路径而变化。
采用最极端的例子(数字4),靠近构造函数的末尾(所以经过多次检查后)你会发现:
if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}
return jQuery.makeArray( selector, this );
...它回答了你的另一个问题:
是的,如果传递一个jquery对象(或任何公开selector
属性的对象,jquery将根据选择器和上下文重建对象,并返回 new 很可能因为这个原因,他们不可能知道它是一个完全成熟的jquery对象,你作为选择器传递。
此外,如果我调用构造函数,我只希望获得一个新对象,而不是获取对我传入的对象的引用。:)
但是如果你不想过多地关心细节(这可能是一件好事,因为有一天它们可能会改变构造函数,破坏你把它全部搞清楚的努力),jquery learning center已经a very good article about how to get the most out of the jquery constructor