You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何两段JavaScript Set添加对象的代码输出结果不同?

为何两段Set处理对象的代码输出结果不同?

你已经清楚JavaScript的Set通过引用地址(准确说是SameValueZero算法)判断对象是否重复,但这两段代码的差异根源不在对象引用,而是Set.add()方法的使用错误。


代码1的问题

代码1:

let list = [ {a:1,b:1},{a:2,b:3},{a:3,b:1} ]

let set = new Set(list);

let newList = [{a:1,b:2},{a:3,b:1}];
set.add(...newList) // 这里是错误用法

let newFilteredList = [...set]
console.log(newFilteredList)

输出结果:

(4) [{...}, {...}, {...}, {...}]
0 : {a: 1, b: 1}
1 : {a: 2, b: 3}
2 : {a: 3, b: 1}
3 : {a: 1, b: 2}

核心原因

Set.prototype.add()仅接受单个参数,它的作用是向Set添加一个元素。你这里用展开运算符...newList,相当于给add传了两个参数,但add只会处理第一个参数{a:1,b:2},第二个参数{a:3,b:1}直接被忽略。最终Set里只有原3个元素加上新增的1个,共4个。


代码2的正确执行

代码2:

let list = [ {a:1,b:1},{a:2,b:3},{a:3,b:1} ] 
let newList = [{a:1,b:2},{a:3,b:1}];
let employees = [...list, ...newList]
let set = new Set(employees)

let newFilteredList = [...set]
console.log(newFilteredList)

输出结果:

(5) [{...}, {...}, {...}, {...}, {...}]
0 : {a: 1, b: 1}
1 : {a: 2, b: 3}
2 : {a: 3, b: 1}
3 : {a: 1, b: 2}
4 : {a: 3, b: 1}

核心原因

这里先把list和newList合并成包含5个对象的数组employees,再用这个数组初始化Set。因为数组里的每个对象都是独立的引用(即使内容相同,两个{a:3,b:1}也是不同的对象实例),所以Set会保留全部5个元素。


补充:给Set添加多个元素的正确方式

如果要像代码1那样给已有Set添加多个元素,不能直接用add(...newList),应该遍历数组逐个添加:

// 方式1:遍历添加
newList.forEach(item => set.add(item));

// 方式2:用扩展运算符创建新Set
set = new Set([...set, ...newList]);

内容的提问来源于stack exchange,提问作者Sadman Jahin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:07:09