add和delete必须配合new set()创建的实例使用,不能用于数组或普通对象;add返回set本身可链式调用,delete返回布尔值;成员唯一性基于samevaluezero算法,对象按引用判等,nan可正确删除;size只读且不响应式,遍历须用for…of或array.from。

add 和 delete 方法必须配合 Set 实例使用,不能直接操作字面量
Set 是引用类型,new Set() 创建的是一个可变对象,但 Set 字面量(比如 {} 或数组)不是 Set 实例,调用 add 或 delete 会报错:TypeError: xxx.add is not a function。
常见错误是误把数组当 Set:比如写 [1, 2, 3].add(4),这根本跑不通;或者试图对普通对象调用 delete,结果删的是对象属性而非集合成员。
- 务必先用
new Set()初始化,再调用方法 -
add返回 Set 实例本身(可链式调用),delete返回布尔值,表示是否成功移除 - Set 成员唯一性由 SameValueZero 算法判定,
0和-0被视为相同,NaN和NaN也被视为相同
add 方法不会覆盖已有值,但要注意原始值与对象的判等差异
add 插入重复值时静默失败,不报错也不改变 Set 内容。这点和 Map 不同——Map 的 set 会覆盖,而 Set 的 add 只认“是否已存在”。
陷阱多出在对象上:{a:1} 和 {a:1} 是两个不同引用,add 会把它们都加进去;但字符串 "1" 和数字 1 是不同类型,会被视为不同成员。
- 基本类型(string/number/boolean/null/undefined)按值比较,安全
- 对象、数组、函数按引用比较,每次
new Object()都是新成员 - 如果要基于内容去重对象,得自己封装逻辑(比如用 JSON.stringify + Map 缓存),Set 原生不支持
delete 方法只删值,不关心索引或顺序,且对不存在的值返回 false
Set 没有索引概念,delete 接收的是具体值,不是位置。传入不存在的值(比如 mySet.delete("missing"))不会报错,只是返回 false —— 这个返回值常被忽略,导致误判删除是否生效。
典型误用:用 if (mySet.delete(x)) { ... } 做条件分支,却没意识到 x 可能根本不在里面,逻辑就跳过了。
- 删除前不必
has检查,delete本身足够安全 - 需要确认是否真删掉了,就依赖它的返回值,而不是假设“只要调用了就成功”
- 注意
NaN:虽然NaN !== NaN,但Set.prototype.delete(NaN)能正确删掉 Set 中的NaN
动态管理时别忘了 size 属性和遍历方式的限制
size 是只读属性,反映当前成员数,但它不会触发响应式更新(比如在 Vue/React 中不会自动重渲染),需要手动监听变化或用计算属性包裹。
遍历时不能用 for…in(它遍历不到 Set 成员),也不能用数组方法如 map 或 filter —— 必须用 for…of、forEach,或转成数组:Array.from(mySet)。
-
mySet.clear()是批量清空的最简方式,比循环delete每个值快得多 - 频繁增删又需同步反映到 UI,建议封装一层类,内部用
add/delete并触发自定义事件 - Set 不支持解构赋值展开为参数(如
func(...mySet)可以,但func(...mySet.values())才是规范写法)










