Object.assign和展开运算符均实现对象浅合并,核心区别在于目标对象是否被修改、空值处理能力及适用场景:基础合并二者等价;配置合并需注意userOptions为空时的保护;修改原对象时展开运算符无法替代Object.assign;数组合并则展开更直观。

Object.assign 和展开运算符(...)本质都能实现对象浅合并,语法转换不难,关键是理解“谁是目标”“是否要保留原对象”“环境是否支持”。下面分场景说清楚。
基础合并:从 Object.assign → 展开运算符
原始写法:
const result = Object.assign({}, objA, objB, objC);
等价的展开写法(更简洁):
const result = { ...objA, ...objB, ...objC };
✅ 两者都创建新对象,不修改原对象;
✅ 属性覆盖逻辑一致:后出现的同名属性覆盖前面的;
✅ 仅适用于对象(不是数组),且只做一层拷贝。
带默认值的配置合并
常见模式是用默认配置 + 用户配置:
const config = Object.assign({}, defaults, userOptions);
直接转为展开运算符,语义更直白:
const config = { ...defaults, ...userOptions };
⚠️ 注意:如果 userOptions 可能为 null 或 undefined,展开运算符会报错,而 Object.assign 能静默跳过。这时可加空值保护:
{ ...(defaults || {}), ...(userOptions || {}) }- 或封装成工具函数:
const safeSpread = (obj) => obj && typeof obj === 'object' ? obj : {};
需要修改已有对象时,不能直接替换
如果原意是复用并更新某个已有对象(比如 Vue/React 中的 state 更新):
Object.assign(existingObj, { name: 'Alice', age: 30 });
❌ 这种写法无法用展开运算符“优雅替代”,因为展开运算符只能生成新对象,不能就地修改。
对应的安全做法是:
- 用展开运算符生成新对象再赋值:
Object.assign(existingObj, { ...existingObj, name: 'Alice', age: 30 });—— 不推荐,绕弯 - 更自然的写法:
Object.assign(existingObj, update);保持原样即可 - 若追求函数式风格,建议改用:
const nextObj = { ...existingObj, ...update };,然后整体替换引用
数组合并也能转,但语法不同
Object.assign 合并数组需显式传入空数组:
const newArr = Object.assign([], arr1, arr2);
展开运算符更直观:
const newArr = [ ...arr1, ...arr2 ];
✅ 数组合并是展开运算符的强项,无需额外包装;
✅ 也支持混用字面量:[ ...arr1, 'extra', ...arr2 ]。

















