【问题标题】:Reusing a jQuery object is faster, but is it always better?重用 jQuery 对象更快,但总是更好吗?
【发布时间】:2014-11-19 21:44:04
【问题描述】:

我在工作中遇到了一些代码如下:

var $divs = $('div');
var $jq   = $([1]);

$divs.each(function () {
    $jq.context = $jq[0] = this;
    // ... do stuff ...
});

我在上面perf'd,它似乎比在函数顶部有$this = $(this); 快得多。在函数内部,$jq 变量有一个标准分类的典型 jQuery 方法,从它调用 (.hasClass(), .data(), .find(), ...),代码按预期工作。

我想知道这里的权衡是什么;即不每次都构造一个新对象,你会失去什么?我只是失去了“历史”(即.pushStack(), .end(), .andSelf(), ...)吗?我应该一直这样做吗?

另外,这是一个命名模式吗?我终其一生都想不出如何在 Google 上进行研究。

【问题讨论】:

  • 你能链接到性能吗?
  • ↑↑↑ 是的,不确定您是否正确比较它,因为$this = $(this);this 包装在 jQuery 对象中,但您没有使用:$jq.context = $jq[0] = this;
  • @Mathletics:添加了指向 jsperf 的链接。 @A.Wolff — 我知道这就是 为什么 重用的 $jq 更快,但我正试图弄清楚权衡是什么。如,“是的,它更快,但它不再正确支持end(),它会杀死一只小猫。”如果可能,我是否应该始终使用上述模式而不是 $this = $(this)

标签: jquery performance object-lifetime


【解决方案1】:

这让我觉得这是一个疯狂的微优化。当然,在基本情况下,重用对象要快一个数量级。但是缓存当前对象的全部目的是为了节省后续操作的时间;在宏伟的计划中,除非您正在处理 数十万 个元素(不要那样做),否则这无关紧要。

你会失去什么

  1. 正常范围:通过将对象存储在迭代的外部范围中,您正在打破回调的闭包。一个明显的例子是,如果你在这里console.log($jq),所有日志条目都将引用同一个对象(循环中的最后一个),而this 对于每次迭代都是唯一的。

    李>
  2. 可读性var $this = $(this)$jq.context = $jq[0] = this 阅读/理解要快得多。

关于“历史”,我看不出你会在这里失去什么。无论哪种情况,您都是从特定对象开始的,因此您从那里进行的任何搜索都将被记录下来。

【讨论】:

  • 嘿 Mathletics -- 你知道缓存是如何工作的吗?这对我来说是全新的,我从未见过它的约定: $jq.context = $jq[0] = this;这是怎么回事?
  • @jamesemanon $jq.context = $jq[0] = this 设置在第 2 行设置的 jquery 对象的根节点和 context 属性,var $jq = $([1]),导致对象本质上与 $(this) 相同。
  • @Mathletics 听起来重用对象非常适合在不需要缓存时迭代集合(如上所述),而且它更像是循环中的单例使用然后丢弃的情况body——除非闭包查找非常昂贵。另外(澄清一点),console.log($jq) 仅在 .each 循环之后包含相同的 DOM 节点,而不是在内部。
  • @Impirator 我不明白你的意思。 Re:console.log,所有log中的对象都会是一样的;这是浏览器记录更改对象的方式的问题。循环完成后,所有日志条目都将包含相同的对象。 (如果您在每次迭代期间暂停并检查,您将看到当前对象。)
  • @Mathletics 我猜 Chrome 已经解决了这个问题;打开控制台并在此页面上插入以下内容:var $divs = $('div'); var $jq = $([1]); $divs.each(function () { $jq.context = $jq[0] = this; console.log('object', $jq); });
猜你喜欢
  • 2017-09-11
  • 2011-04-08
  • 2017-05-11
  • 2010-10-25
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 2016-06-28
  • 2018-03-27
相关资源
最近更新 更多