set.prototype.add()返回调用它的set实例本身,支持链式调用;而map.set()同理返回this,array.push()返回长度故不支持链式,has()/delete()返回布尔值也无法链式。

Set.prototype.add() 返回的是调用它的 Set 实例本身,不是新集合,也不是被添加的元素,更不是布尔值。这个看似简单的设计,恰恰是实现流式(chaining)集合操作的关键前提。
为什么 add() 能支持链式调用
因为它的返回值是 this —— 即当前 Set 对象的引用,而非类似数组方法(如 push() 返回新长度、filter() 返回新数组)那样的“非自身”返回值。这使得多个 add() 可以连续调用,无需中间变量或分号中断。
- ✅ 正确:`new Set().add(1).add(2).add(3)` → 返回包含 {1, 2, 3} 的 Set
- ❌ 错误假设:若返回
true或undefined,链式就会在第一步中断
与 Map.set() 和 Array.push() 的关键对比
理解差异有助于避免混淆:
-
Map.prototype.set(key, value)同样返回this,支持链式:`new Map().set('a', 1).set('b', 2)` -
Array.prototype.push()返回的是数组新长度(数字),不支持链式添加:`[].push(1).push(2)` 会报错(因为 1.push is not a function) -
Set.prototype.has()或delete()返回布尔值,无法继续链式调用 add()
实用流式模式示例
利用 add() 的返回特性,可写出简洁、可读性强的初始化或条件添加逻辑:
- 初始化并预填多个值:
const s = new Set().add('a').add('b').add('c') - 配合三元或逻辑运算符动态添加:
cond && s.add(x) || s.add(y)(注意:这依赖短路,不是纯链式) - 封装流式构建函数:
const buildSet = (...vals) => vals.reduce((s, v) => s.add(v), new Set())
注意事项:不可与“函数式不可变”混淆
流式 ≠ 不可变。每次 add() 都是**原地修改** Set,返回的仍是同一个对象引用:
- `const s = new Set(); const t = s.add(1); s === t` →
true - 若需要不可变语义(如响应式场景),需手动克隆:
new Set([...s].concat(newVals)) - 不要误以为链式调用产生了多个副本——它只是反复操作同一对象
这个设计虽小,却是 JavaScript 集合 API 中为数不多明确支持流畅接口的原生方法之一。掌握它,能让 Set 初始化和增量构建更紧凑自然。










