object.assign()是javascript中用于浅拷贝和对象合并的内置方法,按顺序将源对象的可枚举自有属性复制到目标对象,同名属性后写入者覆盖前者,不处理原型、不可枚举属性及嵌套对象深拷贝。

Object.assign() 是 JavaScript 中用于对象属性合并与浅拷贝的核心工具,它不创建深拷贝,只复制第一层可枚举自有属性,适合快速合并配置、补全默认值或生成新对象快照。
一、基础用法:合并多个源对象到目标对象
语法为 Object.assign(target, ...sources),第一个参数是目标对象(会被修改),后续为源对象(按顺序从左到右拷贝属性)。
说明:
– 若目标对象为 {}(空对象),就等效于“浅拷贝 + 合并”;
– 后续源对象中同名属性会覆盖前面的;
– 原始对象(非 target)不会被修改,但 target 本身会被改变(除非传入不可变对象如 Object.freeze())。
示例:
const defaults = { theme: 'light', fontSize: 14 };
const userConfig = { fontSize: 16, lang: 'zh-CN' };
const finalConfig = Object.assign({}, defaults, userConfig);
// → { theme: 'light', fontSize: 16, lang: 'zh-CN' }
二、实现浅拷贝:用空对象作 target
这是最常见且安全的用法——避免污染原始对象。
- 仅拷贝对象自身可枚举属性(不含原型链上的属性)
- 对嵌套对象只复制引用,不递归处理(即“浅”)
- Symbol 类型的键也会被正确拷贝(ES2015+ 支持)
注意:若源对象含 getter,Object.assign() 会执行 getter 并把返回值作为普通属性赋值,不会保留 getter 本身。
三、属性合并中的覆盖与优先级控制
多个源对象按参数顺序依次拷贝,后出现的同名属性覆盖先出现的:
- 可用于“默认值 ← 用户配置 ← 运行时覆盖”的三级优先级结构
- 若需跳过 undefined 或 null 值,需手动过滤再传入(
Object.assign()不跳过 falsy 值) - 无法自动忽略 undefined 属性,需前置处理:
Object.assign({}, defaults, { ...(userConfig || {}) })
四、注意事项与替代建议
以下情况需谨慎使用或改用其他方式:
- 需要深拷贝时,不能依赖
Object.assign(),应选用structuredClone()(现代环境)、Lodash 的cloneDeep,或手写递归逻辑 - 目标对象为
null或undefined会抛错,建议始终传入一个对象字面量 - 不可枚举属性(如
Object.defineProperty(obj, 'x', { enumerable: false }))不会被拷贝 - 数组被视为对象,其索引会被当作字符串键拷贝,但 length 等属性不参与枚举,慎用于数组合并










