我应该使用expando还是缓存jQuery对象?

时间:2012-04-07 16:56:14

标签: jquery sorting

受到学习jQuery 1.3第7章的启发(第三版中没有),我把这个例程放在一起:

var rows = $table.find('tbody > tr').get();
$.each(rows, function(index, row) {
      var $cell = $(row).children('td').eq(column);
      $(row).data('sortKey',$cell);
});
rows.sort(function(a, b) {
      if ($(a).data('sortKey') < $(b).data('sortKey'))
            return -sortDirection;
      if ($(a).data('sortKey') > $(b).data('sortKey')) 
            return  sortDirection;
      return 0;
});

但我不喜欢在每一行使用$(a)$(b)

问:有没有办法可以缓存$(a)$(b)?作者使用了他称之为 expando 的东西。

  

这种属性,附加到DOM元素但不是普通的DOM   属性,称为expando。这是一个方便存放的地方   关键,因为每个表行元素需要一个。现在,我们可以检查一下   比较器函数中的这个属性,我们的排序是   明显更快。

3 个答案:

答案 0 :(得分:3)

你可以在这里做两个优化。

第一种方法是使用$.data而不是$.fn.data

$.data(a, 'sortKey') // quick
$(a).data('sortKey') // slow

这是优越的,因为它不需要构建一个新的jQuery对象 - 你认为这是一个性能问题是正确的。

第二种是缓存data的结果,所以你只需要做一次。

rows.sort(function(a, b) {
    var aKey = $.data(a, 'sortKey'),
        bKey = $.data(b, 'sortKey');
    if (aKey < bKey) return -sortDirection;
    if (aKey > bKey) return  sortDirection;
    return 0;
});

第三个优化(因为lonesomeday答案是买二送一)是使用jQuery 1.7,它在速度和其他功能方面都优于1.3。

答案 1 :(得分:1)

当然,只需将它们存储在这样的局部变量中:

rows.sort(function(a, b) {
    var aKey = $(a).data('sortKey');
    var bKey = $(b).data('sortKey');
    if (aKey < bKey) return -sortDirection;
    if (aKey > bKey) return sortDirection;
    return 0;
});​

答案 2 :(得分:1)

作者解释说,您需要为某处的每一行存储排序键,但是 不能使用jQuery的.data工具来存储它。而不是这样,他选择在DOM元素上创建一个新属性:

$.each(rows, function(index, row) {
    var $cell = $(row).children('td').eq(column);
    row.sortKey = $cell; // creates a new property!
});

当然上面的代码假定不存在名为sortKey的现有属性(覆盖它,无论它是什么,都可能导致各种问题)。这是一个合理的假设。

之后,您还必须通过用于存储它的相同机制检索排序键:通过访问要比较的两行上的属性:

rows.sort(function(a, b) {
      if (a.sortKey < b.sortKey)
            return -sortDirection;
      if (a.sortKey > b.sortKey)
            return  sortDirection;
      return 0;
});

由于直接属性访问比通过jQuery的.data以及用于实现它的代码快得多,因此可以大幅提高速度。唯一的缺点是你失去了jQuery的抽象数据存储的便利性(保证“只是工作”,你不需要打扰它是如何工作的),因为你现在已经承担了实施的责任数据存储(这里,通过在DOM元素上创建一个新属性)。

作为一个注释,作者使用术语“expando”来准确描述所有JavaScript对象的这个属性:您可以随时在它们上创建新属性。