'$(this)'的成本是多less?

这里的人们经常build议caching从DOM元素创build的jQuery对象,就像这样的代码:

 $('#container input').each(function() { $(this).addClass('fooClass'); $(this).attr('data-bar', "bar"); $(this).css('background-color', 'red'); }); 
  • cachingjQuery对象是否真的提高了我们的代码的性能?
  • 当您将DOM元素传递给jQuery构造函数时,“幕后”会发生什么?

在jQuery 标签信息中出现这个警告:

jQuery函数$()是昂贵的。 多次调用是非常低效的。

那么…这只适用于stringselect器,用正则expression式来parsing它们是什么:

 quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/ 

然后,如果string是一个select器(除id ),jQuery遍历DOMfind一个匹配与其昂贵的findfunction:

 } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector ); } 

所以是的,这是昂贵的,但只有select器才是真的!

如果我们传递一个DOMElement ,那么jQuery唯一的作用是将DOMElement参数保存为新创build的jQuery对象的上下文,并将上下文的长度设置为1:

 // Handle $(DOMElement) if ( selector.nodeType ) { this.context = this[0] = selector; // Selector here is a DOMElement this.length = 1; return this; } 

我用jsPerf做了一些testing,发现cachingjQuery对象只有一点效果:

条形图,如下所述

在Chrome中,它只有7%的慢。 (在IE中,它有点重要:12%。)

要回答你的第二个问题,请看源代码 :

 // Handle $(DOMElement) if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; } 

关于性能差异,如果您正在寻找两者之间的直接比较,那么删除可能导致结果偏斜的任何额外代码(如DOMselect和其他不直接相关的方法)将会很有帮助。

http://jsperf.com/this-cost/2

在这里输入图像说明

在更真实的世界里,你的testing显示的相对差异很小

另外需要记住的是,每次创build一个jQuery对象时,都需要为其分配内存,这就增加了垃圾回收器需要做的工作。

所以我认为人们提出caching的原因是从某种原则的angular度来看的。 额外的工作正在完成,虽然通常不会有明显的影响,但最终还是需要一些可以轻易避免的开销。

所有运行时性能testing在这里错过的一件事是另一个主要的考虑因素:

networking带宽。

$(this)caching到局部variables中通常会减小脚本的大小,特别是缩小时(因为不能从四个字符中减less)。

考虑:

 function hello(text) { $(this).attr(); $(this).css(); $(this).data(); $(this).click(); $(this).mouseover(); $(this).mouseleave(); $(this).html(text); } hello('Hello world'); 

Closure编译器的缩小输出是

 function hello(a){$(this).attr();$(this).css();$(this).data();$(this).click();$(this).mouseover();$(this).mouseleave();$(this).html(a)}hello("Hello world"); 

这节省了39个字节(20%)。 现在考虑:

 function hello(name) { var $this = $(this); $this.attr(); $this.css(); $this.data(); $this.click(); $this.mouseover(); $this.mouseleave(); $this.html(name); } hello('Hello world'); 

缩小的输出是

 function hello(b){var a=$(this);a.attr();a.css();a.data();a.click();a.mouseover();a.mouseleave();a.html(b)}hello("Hello world"); 

这节省了74个字节(37%),节省了将近一倍的字节。 很明显,大型脚本中真实世界的节省将会降低,但是仍然坚持通过caching来显着减less脚本的大小。

真的,caching$(this)只有一个好处。 你会得到微不足道的,但可衡量的运行时性能提升。 更重要的是,您可以减less通过networking传输的字节数,并且直接转化为更多的美元,因为更快的页面负载等于更多的销售额 。

当你这样看的时候,实际上可以说重复$(this)并且不caching它会有一个可量化的美元成本