object.assign按参数顺序后覆盖前,仅处理第一层自有可枚举字符串键:null/undefined源对象被跳过,嵌套对象整块替换,symbol和原型属性不参与。

Object.assign 处理合并冲突时,没有“智能判断”或“条件优先”,只有一条铁律:**按参数顺序,后出现的同名属性无条件覆盖先出现的**。它不看值类型、不看来源意图、不区分配置层级,只认调用时的书写位置。
参数顺序即优先级顺序
所有源对象从左到右依次处理,每个对象的属性逐个写入目标对象。一旦某个键被写入,后续参数中同名键就会直接替换它:
- 第一个源对象的属性最先写入,但随时可能被覆盖
- 第二个源对象中同名键会覆盖第一个中的对应值
- 第三个源对象继续覆盖前两个中同名键的值
- 以此类推,最右侧的源对象拥有最终决定权
null 和 undefined 不打断顺序,但也不参与覆盖
它们会被 Object.assign 安静跳过,既不报错,也不影响后续参数的执行位置:
-
Object.assign({}, {a: 1}, null, {a: 2})→{a: 2}(null被忽略,{a: 2}仍是第三个参数,覆盖生效) -
Object.assign({}, {x: 'old'}, undefined, {x: 'new'})→{x: 'new'} - 注意:
undefined作为属性值(比如{x: undefined})会被正常写入,这和undefined作为整个源对象是两回事
嵌套对象整块替换,不合并内部字段
覆盖只发生在第一层键上。如果多个源对象都有 user 这个键,不管它们的 user 是什么结构,后一个会整个替换前一个:
-
{user: {name: 'Alice'}}和{user: {age: 30}}合并后是{user: {age: 30}},name消失 - 这不是“冲突解决”,而是“值替换”——
user键对应的整个对象引用被更新了 - 想保留原
user中的字段?必须手动拆解,或改用深合并工具
只拷贝自有可枚举属性,原型和 Symbol 不参与
Object.assign 不读取原型链,也不处理 Symbol 键,哪怕它们是可枚举的:
- 继承来的
toString或自定义的不可枚举属性(enumerable: false)完全不会被复制 -
const sym = Symbol('key'); const obj = {[sym]: 'value'};→Object.assign({}, obj)不包含该 Symbol 键 - 这意味着“优先级”只对显式定义在对象自身的字符串键有效,其他类型的键根本不在竞争范围内
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











