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()会检查每个节点是否已存在于数组中,若存在则跳过。- 由于是原地修改,
uniqueArray和combined.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 的内部机制;
- 在合并多个选择器结果时,避免重复元素带来的问题;
- 提升代码健壮性和性能。
尽管现代开发中 Set 和 Array.from(new Set()) 更常用于去重,但了解 jQuery.unique() 依然有意义——尤其当你维护旧项目或阅读 jQuery 源码时。
掌握它,不只是学会一个 API,更是理解“去重”背后的设计哲学:用空间换时间,用唯一标识代替暴力比较。
本文所介绍的
jQuery.unique()方法,是 jQuery 生态中一个虽小却精巧的功能,值得每一位前端开发者深入理解。