jQuery.unique() 方法(完整教程)

jQuery.unique() 方法简介

在前端开发中,处理 DOM 元素时经常会遇到重复数据的问题。比如,从多个选择器中获取元素,最终结果中可能包含相同的节点多次出现。这时候,我们就需要一个方法来“去重”——而 jQuery 提供的 jQuery.unique() 方法,正是为解决这类问题量身定制的工具。

这个方法的作用是:对传入的数组或类似数组的对象进行去重处理,确保结果中每个元素只出现一次。它特别适用于 DOM 节点数组,能够智能识别重复的元素节点,从而返回一个干净、无重复的集合。

需要注意的是,jQuery.unique() 是 jQuery 内部使用的方法,官方并不推荐直接在生产环境中调用,但了解它的原理和使用场景,有助于我们理解 jQuery 的底层机制,提升代码质量。


为什么需要去重?真实开发场景

想象一下这样的场景:你在做一个动态表格,用户点击某个按钮后,通过多个选择器(如 .row.active[data-selected])获取所有符合条件的行。这些选择器可能会有重叠,比如某一行同时满足多个条件。

如果直接合并这些结果,最终列表里就可能出现同一行被多次添加的情况。这不仅浪费内存,还可能导致后续操作(如事件绑定、样式修改)出错。

这时候,jQuery.unique() 就像一个“过滤筛子”——它能帮你把重复的 DOM 节点筛掉,只留下唯一的那些。

// 示例:多个选择器获取元素,结果可能重复
const $rows1 = $('.row');
const $rows2 = $('.active');
const $rows3 = $('[data-selected]');

// 合并所有元素(可能包含重复项)
const allRows = $rows1.add($rows2).add($rows3);

// 使用 jQuery.unique() 去重
const uniqueRows = jQuery.unique(allRows.get());

// 输出去重后的结果
console.log('去重后元素数量:', uniqueRows.length);

注释

  • allRows 是通过 add() 方法合并的 jQuery 对象,可能包含重复的 DOM 节点。
  • .get() 将 jQuery 对象转换为原生数组,以便传入 jQuery.unique()
  • jQuery.unique() 返回的是去重后的原生数组,不能再直接用 jQuery 方法操作。

jQuery.unique() 方法的参数与返回值

这个方法接收一个数组或类数组对象作为参数,它会原地修改传入的数组,并返回同一个数组的引用(即返回值与输入相同)。

参数说明

参数 类型 说明
array Array 需要去重的数组或类数组对象,通常包含 DOM 节点

返回值

  • 返回值是去重后的数组本身(即原数组被修改)
  • 仅适用于 DOM 节点的去重,不适用于普通数据类型(如字符串、数字)
// 示例:使用 jQuery.unique() 处理 DOM 节点数组
const elements = document.querySelectorAll('.item');
const $elements = $(elements); // 转为 jQuery 对象

// 通过 add() 合并多个选择器结果
const combined = $elements.add('.highlight').add('.selected');

// 转为原生数组并去重
const uniqueArray = jQuery.unique(combined.get());

console.log('原始长度:', combined.length);
console.log('去重后长度:', uniqueArray.length);

注释

  • combined.get() 返回一个原生数组,包含所有匹配的 DOM 节点。
  • jQuery.unique() 会检查每个节点是否已存在于数组中,若存在则跳过。
  • 由于是原地修改,uniqueArraycombined.get() 指向同一对象,修改其内容会影响原数组。

内部原理:它是如何工作的?

jQuery.unique() 的内部实现基于一个巧妙的机制:使用一个临时属性来标记已见过的节点

当它遍历数组时,会对每个节点添加一个唯一的 jQuery.expando 属性(如 jQuery.expando = "12345"),并记录该属性值。如果某个节点已经存在该属性,说明它已经处理过,跳过即可。

这种方式避免了逐个比较节点引用的性能开销,效率非常高。

// 模拟 jQuery.unique() 的简化版本(仅供理解)
function unique(arr) {
  const seen = {};
  const result = [];

  for (let i = 0; i < arr.length; i++) {
    const node = arr[i];
    const key = node.nodeType ? node.nodeType + node.nodeName + node.nodeValue : node;

    if (!seen[key]) {
      seen[key] = true;
      result.push(node);
    }
  }

  // 原地修改原数组
  arr.length = 0;
  for (let i = 0; i < result.length; i++) {
    arr[i] = result[i];
  }

  return arr;
}

注释

  • 这是简化版逻辑,真实实现更复杂,考虑了 DOM 节点的唯一性标识。
  • node.nodeType 是判断是否为节点的重要依据。
  • key 的构造方式确保相同节点具有相同标识。
  • arr.length = 0 是为了清空原数组,再重新填充去重后的元素。

实际应用案例:动态列表去重

假设你正在开发一个任务管理应用,支持多标签筛选。用户可以选择“已完成”、“高优先级”、“本周任务”等标签,每个标签对应不同的 CSS 类。

当用户点击“全部”时,你需要合并所有符合条件的列表项,并确保每项只显示一次。

<ul id="task-list">
  <li class="task completed high-priority">写日报</li>
  <li class="task completed">整理资料</li>
  <li class="task high-priority">回邮件</li>
  <li class="task">开会</li>
</ul>
// 获取所有匹配的列表项
const completedTasks = $('.completed');
const highPriorityTasks = $('.high-priority');
const allTasks = completedTasks.add(highPriorityTasks);

// 转为原生数组并去重
const uniqueTasks = jQuery.unique(allTasks.get());

// 渲染去重后的结果
uniqueTasks.forEach(task => {
  console.log('显示任务:', task.textContent);
});

注释

  • allTasks 是合并后的 jQuery 对象,可能包含重复的 <li> 元素。
  • jQuery.unique(allTasks.get()) 去除重复节点。
  • forEach 遍历结果,输出每项内容。
  • 最终输出中,“写日报”只出现一次,即使它同时属于“completed”和“high-priority”。

常见误区与注意事项

1. 不能用于普通数据类型

jQuery.unique() 仅对 DOM 节点有效,对字符串、数字、对象等无效。

const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNums = jQuery.unique(numbers);

console.log(uniqueNums); // [1, 2, 2, 3, 4, 4, 5] —— 未去重!

原因jQuery.unique() 内部依赖节点的唯一性标识,普通数组无法使用该机制。

2. 原地修改,需谨慎使用

由于 jQuery.unique() 直接修改传入的数组,若后续还需要原始数据,必须提前复制。

const original = [el1, el2, el3, el1]; // el1 重复
const copy = [...original]; // 深拷贝
const result = jQuery.unique(copy);

console.log('原始数据:', original); // 未被修改
console.log('去重后:', result); // 去重结果

3. 不适用于非 DOM 对象

如果你传入的是普通对象数组,jQuery.unique() 无法识别重复项。

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 1, name: 'Alice' } // 重复
];

const uniqueUsers = jQuery.unique(users);
console.log(uniqueUsers); // 仍然包含两个对象,未去重

解决方案:应使用 Set 或自定义去重逻辑。


总结:掌握 jQuery.unique() 的价值

jQuery.unique() 方法虽然不常被直接调用,但它揭示了 jQuery 在处理 DOM 操作时的高效设计思想:通过内部标识快速判断唯一性,避免冗余比较

对于初学者而言,理解这个方法,能帮助你:

  • 更好地理解 jQuery 的内部机制;
  • 在合并多个选择器结果时,避免重复元素带来的问题;
  • 提升代码健壮性和性能。

尽管现代开发中 SetArray.from(new Set()) 更常用于去重,但了解 jQuery.unique() 依然有意义——尤其当你维护旧项目或阅读 jQuery 源码时。

掌握它,不只是学会一个 API,更是理解“去重”背后的设计哲学:用空间换时间,用唯一标识代替暴力比较

本文所介绍的 jQuery.unique() 方法,是 jQuery 生态中一个虽小却精巧的功能,值得每一位前端开发者深入理解。