jQuery对象:caching还是不caching?
我有一些麻烦来自我的Javascript(JS)代码,因为我有时需要在同一个函数中多次访问相同的DOM元素。 这里也提供了一些推理。
从性能的angular度来看,创build一个jQuery对象一次然后caching它更好,还是更好地创build相同的jQuery对象? 例:
function(){ $('selector XXX').doSomething(); //first call $('selector XXX').doSomething(); //second call ... $('selector XXX').doSomething(); // n-th call }
要么
function(){ var obj = $('selector XXX'); obj.doSomething(); //first call obj.doSomething(); //second call ... obj.doSomething(); // n-th call }
我猜想答案可能取决于“n”的值,所以假设n是一个“小”数字(例如3),然后是一个中等数字(例如10),最后是一个大数字(例如30,对象用于for循环中的比较)。
提前致谢。
$('#something').something().somethingelse();
对于大多数 jQuery操作来说,如果n大于1,caching元素,或者将操作链接在一起(可以使用$('#something').something().somethingelse();
因为他们通常返回包装本身)。 顺便说一下,以货币符号$
开头的cachingvariables的名称已经成为了一个标准,所以在后面的代码中显然你正在对一个jQuery集合执行一个操作。 所以你会看到很多人做var $content = $('#content');
那么$content.find('...');
稍后的。
第二是优越。 最重要的是,它更干净。 将来,如果你想改变你的select器,你只需要改变一个地方。 否则你需要在N个地方改变它。
其次,它应该performance得更好,虽然用户只会注意到特别沉重的dom,或者如果你正在调用这个function很多。
如果从不同的angular度来看这个问题,正确的答案是显而易见的。
在第一种情况下,您在每个出现的地方复制select逻辑。 如果更改元素的名称,则必须更改每个事件。 这应该是足够的理由不这样做。 现在你有两个select – 要么caching元素的select器或元素本身。 使用元素作为对象比使用名称更有意义。
在性能方面,我认为效果可以忽略不计。 也许你能够find这个特定用例的testing结果:cachingjQuery对象vs总是重新select它们。 性能可能会成为一个问题,如果你有一个大的DOM,并做了很多的查找,但你需要亲自看看,如果是这样的话。
如果您想要查看您的对象占用了多less内存,则可以使用Chrome浏览器堆分析器并在此处查看。 我不知道是否有类似的工具可用于其他浏览器,可能实现的性能差异很大,特别是在IE的情况下,但它可能会满足您的好奇心。
国际海事组织,你应该使用第二个变种,将select的结果存储在一个对象中,没有太多提高性能,但有尽可能less的重复逻辑。
至于caching$(this)
,我同意Nick Craver的回答 。 正如他在那里所说的,你应该尽可能地使用链接 – 清理你的代码并解决你的问题。
我几乎总是喜欢caching的jQuery对象,但好处很大程度上根据你正在使用您的select器。 如果你使用的是id,那么这个好处远远less于你使用select器的types。 另外,不是所有的select器都是相同的,所以当你编写select器的时候要记住这一点。
例如: $('table tr td')
是一个很差的select器。 尝试使用上下文或.find(),它会产生巨大的差异。
我喜欢做的一件事是在我的代码中放置计时器,以查看它的效率。
var timer = new Date(); // code here console.log('time to complete: ' + (new Date() - timer));
大多数caching的对象将在不到2毫秒的时间内执行,因为您首先需要查找元素,然后执行操作,因为全新的select器需要相当长的时间。
在JavaScript中,函数通常是短暂的,特别是当被浏览器托pipe时。 但是,一个函数的作用域可能会超过这个函数。 例如,当你创build一个闭包时会发生这种情况。 如果你想防止长时间引用jQuery
对象,你可以给任何在你完成该variables时引用它的variables赋值,或者使用间接方法来创build闭包。 例如:
var createHandler = function (someClosedOverValue) { return function () { doSomethingWith(someClosedOverValue); }; } var blah = function () { var myObject = jQuery('blah'); // We want to enable the closure to access 'red' but not keep // myObject alive, so use a special createHandler for it: var myClosureWithoutAccessToMyObject = createHandler('red'); doSomethingElseWith(myObject, myClosureWithoutAccessToMyObject); // After this function returns, and assuming doSomethingElseWith() does // not itself generate additional references to myObject, myObject // will no longer have any references and be elligible for garbage // collection. }
因为jQuery(selector)
可能最终不得不运行昂贵的algorithm,或者甚至为了复杂的expression式走一些浏览器无法直接处理的DOM树,最好是caching返回的对象。 另外,正如其他人所提到的,为了代码清晰,最好caching返回的对象以避免多次inputselect器。 也就是说,DRY代码通常比WET代码更容易维护。
但是,每个jQuery对象都有一定的开销。 因此,在全局variables中存储大量的jQuery对象可能是浪费的 – 除非实际上需要对大量的这些对象进行操作,而仍将它们视为不同的对象。 在这种情况下,可以通过直接cachingDOM元素的数组,并使用jQuery(DOMElement)
构造函数来保存内存,这些构造函数在迭代时基本上应该是空闲的。
虽然,正如人们所说,你只能通过对比不同的方法来了解你的特定情况的最佳方法。 即使理论听起来也很难预测现实;-)。