object.assign 直接修改目标对象并返回该对象,仅执行浅拷贝、不触发 setter、忽略不可枚举属性和原型链属性,合并顺序决定覆盖结果且不可逆。

Object.assign 会直接修改目标对象,这是它最核心也最容易被忽视的行为。它不是“生成新对象再赋值”,而是把源对象的属性“贴”到第一个参数所指的对象上,并原地返回这个被改过的对象。
目标对象被改写是默认行为
只要 target 是一个已有对象(比如 this.state、配置项或某个变量引用),调用 Object.assign(target, source) 后,target 就已变更。后续任何依赖它原始状态的逻辑都可能出错。
- 返回值和 target 指向同一个内存地址,console.log(target === returnedTarget) 总是 true
- 如果 target 是 null 或 undefined,会抛出 TypeError;但 source 为 null/undefined 会被跳过,不报错
- 原始数据类型(如字符串、数字)作 target 时,会被强制转成包装对象,结果往往不符合预期
浅拷贝导致嵌套对象共享引用
Object.assign 只复制第一层属性值。当属性值本身是对象、数组或函数时,复制的是引用,不是副本。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 修改 mergedObj.nested.prop 会影响 originalObj.nested.prop
- 这种影响在 React 的 state 更新、Vue 的响应式对象合并中尤其危险
- 无法通过 Object.assign 实现真正的深克隆,需用 structuredClone()、JSON 序列化或递归工具
覆盖逻辑不可逆且顺序敏感
属性按参数顺序从左到右合并,后出现的同名属性会覆盖前面的值,且覆盖发生在 target 上,没有回滚机制。
- Object.assign({}, defaults, userConfig) 中,userConfig 的 b 会覆盖 defaults 的 b
- 但如果误写成 Object.assign(defaults, userConfig),defaults 就永久被改写了
- 多个 source 里重复 key 的处理完全依赖传入顺序,容易因参数位置调整引发隐蔽 bug
绕过 setter 和不可枚举属性
Object.assign 不触发目标对象的 setter,也不复制原型链上的属性或 enumerable: false 的自有属性。
- 带 setter 的属性(如 Vue 的 computed 或自定义 set)不会被调用,赋值直接写入内部
- 用 Object.defineProperty 定义的不可枚举属性、Symbol 属性(可枚举的除外)均不会被拷贝
- 继承来的属性(来自 prototype)一律忽略,只处理对象自身的可枚举属性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










