object.assign 是 javascript 中实现浅拷贝和多对象合并的内置方法,仅复制可枚举自有属性,对嵌套引用类型不递归拷贝,修改子对象仍会影响原对象。

Object.assign 是 JavaScript 中用于对象属性复制的内置方法,它能实现浅拷贝和多对象属性合并,但要注意它只复制**可枚举、自有属性**,且是**浅层复制**(嵌套对象仍共享引用)。
用 Object.assign 实现浅拷贝
将空对象作为目标,原对象作为源,即可创建一个新对象,包含原对象所有可枚举自有属性的副本:
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);
copy.a = 99; // 不影响 original.a
console.log(original.a); // 1 ✅
copy.b.c = 99; // 会影响 original.b.c ❌(因为 b 是引用类型)
console.log(original.b.c); // 99
注意:这不是深拷贝,对嵌套对象或数组的修改仍会反映到原对象上。
用 Object.assign 合并多个对象
Object.assign 支持多个源对象,按顺序依次把属性复制到目标对象中,后复制的属性会覆盖前面同名属性:
const defaults = { theme: 'light', lang: 'zh', timeout: 5000 };
const userConfig = { theme: 'dark', fontSize: 16 };
const runtimeConfig = { timeout: 3000 };
const finalConfig = Object.assign({}, defaults, userConfig, runtimeConfig);
// 结果:{ theme: 'dark', lang: 'zh', timeout: 3000, fontSize: 16 }
- 第一个参数是目标对象,通常传空对象
{}避免污染原对象 - 后续参数是源对象,从左到右依次合并,同名属性以右侧为准
- 如果源对象为
null或undefined,会被跳过(不报错)
常见陷阱与注意事项
-
只处理自有、可枚举属性:不会复制原型链上的属性,也不会复制
Symbol属性(除非显式传入) - 无法拷贝访问器属性(getter/setter):只会复制 getter 的返回值,丢失原有逻辑
-
不能拷贝不可枚举属性:如
Object.defineProperty(obj, 'x', { value: 1, enumerable: false })中的x -
null/undefined 源对象被忽略,但传入字符串会转成类数组对象(如
"abc"→{0:'a',1:'b',2:'c'})
替代方案提示
若需深拷贝,Object.assign 不适用,可考虑:
-
JSON.parse(JSON.stringify(obj))(简单场景,不支持函数、undefined、Date、RegExp 等) - Lodash 的
_.cloneDeep() - 结构化克隆(
structuredClone(),现代浏览器支持)
若要合并时保留某些策略(如深度合并、跳过 undefined),建议封装工具函数或使用成熟库。











