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

为何JavaScript对象合并会覆盖重复属性,数组扩展仅做元素拼接?

为什么JavaScript扩展运算符在合并对象和数组时行为不同?

这本质是由对象和数组的核心特性差异决定的:

对象的属性唯一性导致覆盖

对象的核心是「键值对集合」,同一个对象中不允许存在重复的属性名——这是JavaScript对象的基础规则。

当用扩展运算符合并对象时,逻辑是按顺序将后续对象的属性依次“写入”新对象:如果遇到和前面重复的属性名,后面的属性值会直接覆盖前面的,这和你直接给对象赋值obj.b = 4会覆盖原有obj.b的逻辑完全一致。

比如你给出的例子:

const a = {'a': 1, 'b': 2}
const b = {'b': 4, 'c': 3}
console.log({...a, ...b})

新对象先复制a的所有属性,再复制b的属性,当遇到重复的b时,b的4就覆盖了a里的2,最终得到{a:1, b:4, c:3}。

数组的元素有序性导致拼接

数组的核心是「有序元素列表」,它允许存在重复元素,元素的标识是索引而非值本身。

扩展运算符处理数组时,只是简单地把每个数组的元素依次展开,然后按顺序拼接成新数组——它不会检查元素值是否重复,因为重复元素在数组里是完全合法的。

比如你的数组例子:

const c = [1,2]
const d = [2,3]
console.log([...c, ...d])

先展开c得到1,2,再展开d得到2,3,把这些元素按顺序拼起来,就得到[1,2,2,3],完全保留了两个数组里的所有元素。

设计逻辑的合理性

这种差异是符合开发者直觉的:

  • 对象合并时,我们通常希望后续的配置能覆盖前面的(比如用默认配置+自定义配置的场景),所以“后面覆盖前面”是合理的规则;
  • 数组拼接时,我们大多只是想把两个列表的元素合在一起,而不是自动去重或覆盖,所以直接保留所有元素是更通用的设计。

内容的提问来源于stack exchange,提问作者Rohan Bisht

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:40:34