浅拷贝配合扩展运算符({...obj})是最快捷的顶层配置合并方式,因其语法简洁、执行高效、原生支持且不可变;但仅浅层展开,同名键后覆盖前,嵌套对象会被整体替换而非合并。

浅拷贝配合扩展运算符({...obj})是合并多个配置最轻量、最常用的方式,适合顶层字段独立、嵌套结构不深或可规避覆盖风险的场景。
为什么扩展语法和浅拷贝能“快速”合并
扩展运算符本质上就是语法糖形式的浅拷贝,它把对象自身可枚举属性一层展开,按顺序写入新对象。和 Object.assign({}, a, b, c) 行为完全一致,但更简洁、可读性更高。
- 不修改原对象,天然不可变 —— 每次都生成全新对象
- 属性覆盖逻辑明确:后出现的对象同名键会直接替换前一个
- 执行快、无依赖、浏览器/Node.js 全平台原生支持
典型多配置合并写法
比如同时融合默认配置、环境配置、用户传参三者:
const defaults = { timeout: 5000, method: 'GET', retry: 3 };
const envConfig = process.env.NODE_ENV === 'production'
? { timeout: 2000, retry: 1 }
: {};
const userConfig = { method: 'POST', headers: { 'X-Trace': '123' } };
const finalConfig = { ...defaults, ...envConfig, ...userConfig };
// 结果:{ timeout: 2000, method: 'POST', retry: 1, headers: { 'X-Trace': '123' } }
注意:headers 是整个被替换的——如果 defaults.headers 原本有 { 'Content-Type': 'json' },它会被 userConfig.headers 完全覆盖,不会保留原有字段。
避开嵌套覆盖坑的实用技巧
当必须保留嵌套结构(如 api、ui、headers),又不想引入深合并库时,可以手动分层展开:
- 把嵌套对象单独提取出来再合并:
const api = { ...defaults.api, ...userConfig.api }; - 再组装进顶层:
const config = { ...defaults, api, ...userConfig };(注意:这里...userConfig不再含api字段,避免二次覆盖) - 或者用解构剔除干扰项:
const { api: userApi, ...restUser } = userConfig;,再分别处理
什么情况下别硬扛,该换方案
以下情况说明浅拷贝+扩展语法已力不从心,继续拼凑容易埋雷:
- 配置中大量使用多层嵌套(如
request.headers.authorization、ui.modals.confirm.title),且要求只改其中一项 - 项目已装 Lodash,直接用
_.merge(defaults, userConfig)更安全 - 运行环境支持 Chrome 98+/Node.js 17+,可用
structuredClone()配合递归合并逻辑 - 配置来自外部 API 或表单输入,结构不确定,需防御性处理


















