推荐使用 new Set() 去重,因其最简、最快、最安全,且在 uni-app 的小程序和 H5 环境全平台支持;避免污染 Array.prototype,注意正确写法为 Array.from(new Set(arr)) 或 [...new Set(arr)],对象需 JSON 序列化处理,搜索历史等场景还需保序置顶。

直接用 new Set() 就行,最简、最快、最安全,尤其在 uni-app 的小程序和 H5 环境里完全够用。
为什么推荐 new Set() 而不是改 Array.prototype
uni-app 编译到微信小程序时,运行环境是基础库 2.27+(2026 年主流已到 3.x),Set 全平台支持;而给 Array.prototype 加 unique 方法看似方便,实际容易引发冲突:
- 多个插件或组件都定义同名
unique,后加载的会覆盖前一个 - 某些平台(如支付宝小程序)对原型污染更敏感,可能报错或静默失败
-
uni.getStorageSync读出的数组是普通数组,但如果你在别处用了Object.create(null)类型的去重逻辑,遇到undefined或对象元素就会漏判
new Set() 的正确写法和边界注意
别直接写 [new Set(arr)]——这是常见笔误,会导致返回一个包含 Set 实例的数组,而不是去重后的值数组。
正确写法只有两种(任选其一):
-
Array.from(new Set(arr))—— 兼容性最好,IE11 都能跑(虽然 uni-app 不需兼容 IE) -
[...new Set(arr)]—— 更简洁,但要注意:如果arr是类数组(比如arguments或某些 DOM 集合),得先转成真数组再展开
示例:
const arr = [1, 2, '2', 2, 1, {a:1}, {a:1}];
const unique = Array.from(new Set(arr.map(JSON.stringify))).map(JSON.parse);
// 对象去重必须序列化,否则 {a:1} !== {a:1}
搜索历史这类场景,别只去重,还要保序+置顶
比如用户搜了 "苹果",再搜 "香蕉",再搜 "苹果",你希望最终历史是 ["苹果", "香蕉"](最新一次在前),而不是简单去重后的原始顺序。
这时候不能只靠 Set,得手动控制顺序:
- 先用
filter把旧的同名项剔除:history.filter(item => item !== keyword) - 再把新词拼到开头:
[keyword, ...filtered] - 最后截取长度(比如最多 10 条):
[keyword, ...filtered].slice(0, 10)
完整片段:
const saveSearchHistory = (keyword) => {
if (!keyword || typeof keyword !== 'string' || !keyword.trim()) return;
const history = uni.getStorageSync('search_history') || [];
const filtered = history.filter(item => item !== keyword);
const newHistory = [keyword, ...filtered].slice(0, 10);
uni.setStorageSync('search_history', newHistory);
};
对象数组去重、字符串 trim 后比较、空值防御、本地缓存键名拼写——这些细节比“怎么去重”本身更容易出问题。写完别急着提交,拿 [' 苹果 ', '', null, '苹果'] 这种数据测一遍。











