object.keys本身不直接去重,但可借助对象键名唯一性实现原始值去重:将数组元素转为字符串作key存入临时对象,再用object.keys提取键名数组。

Object.keys 本身不直接用于数组去重,它只是返回对象自身可枚举属性的键名数组。但你可以借助“对象键名天然唯一”这一特性,配合 Object.keys(或更常用的是 Object.keys 的前提——构造一个临时对象)来实现基于字符串键的去重。关键在于:把数组元素转为字符串作为对象的 key,利用对象自动覆盖同名 key 的行为完成“去重”,再提取 key 列表。
为什么能用对象键名去重?
JavaScript 中,对象的属性名(key)在同一个对象内必须唯一。即使你多次赋值给同一 key,后一次会覆盖前一次,最终只保留一个。这个特性可以当作一个“自动去重的容器”:
- 数字、字符串、布尔值等基础类型作为 key 时,会被隐式转为字符串(如
{1: 'a', '1': 'b'}实际只有'1': 'b'); -
null和undefined也会被转成"null"和"undefined"; - 对象、数组等引用类型作为 key 会被统一转为
"[object Object]",所以不能直接用于引用类型去重(需额外处理,比如 JSON.stringify)。
基础用法:字符串/数字数组去重
适用于元素全是原始值(且不需要保持顺序)的场景:
const arr = ['a', 'b', 'a', 1, 2, 1];
const uniqueObj = {};
arr.forEach(item => {
uniqueObj[item] = true; // 利用 key 唯一性,重复项自动被覆盖
});
const result = Object.keys(uniqueObj); // ['a', 'b', '1', '2']
// 注意:Object.keys 返回的是字符串数组,数字 1 变成了 '1'
如果希望结果保持原始类型(比如数字还是数字),可以用 Object.getOwnPropertyNames 配合 JSON.stringify 或手动转换,但更推荐下面这种兼容性更好的写法:
const arr = ['a', 'b', 'a', 1, 2, 1];
const uniqueSet = {};
const result = [];
arr.forEach(item => {
const key = typeof item === 'object' ? JSON.stringify(item) : String(item);
if (!uniqueSet[key]) {
uniqueSet[key] = true;
result.push(item);
}
});
// result = ['a', 'b', 1, 2]
注意:和 Set 的区别
现代 JS 更推荐用 new Set(arr) 去重,原因包括:
-
Set保留原始类型(1还是1,不是'1'); -
Set支持NaN和-0的正确区分(对象 key 会把NaN当作'NaN',丢失区分能力); -
Set语法简洁:[...new Set(arr)]; -
Object.keys方案本质是“模拟 Set”,多了一层对象创建和键转换,性能略低,可读性也稍差。
什么情况下才考虑用 Object.keys + 对象?
极少,除非你在非常老的环境(无 Set)且只处理简单字符串/数字,并接受类型转换。更现实的用途是:
- 统计频次:
obj[item] = (obj[item] || 0) + 1; - 做存在性检查(比
includes快,尤其大数据量); - 配合
Object.keys(obj).length获取去重后数量(但不如new Set(arr).size直观)。
真正需要“用 Object.keys 实现去重”,通常说明设计可以优化——优先用 Set,需要兼容旧环境时用 reduce 或 filter + indexOf。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











