Object.assign的同名属性覆盖是按参数顺序的赋值规则:后参数同名属性覆盖前参数,null/undefined被跳过但不改变顺序,原始值转包装对象后无属性可拷贝,嵌套对象整体替换而非深度合并。

同名属性覆盖不是“算法”,而是一条明确的赋值规则:按参数顺序,后出现的源对象中同名属性直接覆盖先出现的——包括目标对象自身已有的属性。
覆盖只看传参位置,不看对象类型或内容
Object.assign 的行为完全由调用时的参数顺序决定,和对象是配置、数据还是空对象无关。只要它出现在参数列表中靠后的位置,它的同名属性就拥有更高优先级。
- 第一个参数(target)的同名属性会被第二个参数覆盖
- 第二个参数的同名属性会被第三个参数覆盖
- 以此类推,最后一个 source 拥有最终解释权
null 和 undefined 会被跳过,但不会打断顺序
如果某个 source 是 null 或 undefined,Object.assign 会安静地忽略它,继续处理下一个参数。这不会改变后续参数的覆盖优先级。
-
Object.assign({}, {a: 1}, null, {a: 2})→{a: 2} -
Object.assign({}, {a: 1}, undefined, {a: 3})→{a: 3}
原始值(如字符串、数字)等效于空对象
传入字符串 'abc' 或数字 42 时,它们会被转为包装对象(new String('abc')、new Number(42)),但这些包装对象没有可枚举自有属性,所以实际不拷贝任何东西,也不影响覆盖逻辑。
-
Object.assign({}, {x: 1}, 'hello', {x: 99})→{x: 99} - 中间的字符串没起作用,但末尾对象仍按位置生效
浅合并意味着嵌套对象不被拆解
覆盖发生在第一层键上,嵌套对象被视为一个整体值。即使两个 source 都有 user: { name: 'A' },后者的整个 user 对象会替换前者,而不是合并内部字段。
-
Object.assign({}, {user: {name: 'Alice'}}, {user: {age: 30}})→{user: {age: 30}} -
user.name消失了,因为user键被完整替换了










