浅拷贝不支持多层递归合并,仅处理第一层属性;Object.assign()和展开运算符属浅拷贝,嵌套对象会被整体替换而非合并,需通过分层设计、手动提取或改用deepAssign/structuredClone等方案实现真正多级合并。

浅拷贝本身不支持多层(嵌套)配置的递归合并,它只能处理第一层属性。所谓“利用浅拷贝技巧快速合并多层配置项”,实际是指在明确理解其局限的前提下,用 Object.assign() 或展开运算符({...})高效完成顶层结构的组合,并通过合理设计配置结构、分层策略或前置预处理,规避深层覆盖带来的意外丢失——而不是让浅拷贝去“做深的事”。
明确浅拷贝的行为边界
浅拷贝只复制对象自身可枚举属性的值:
- 基础类型(string/number/boolean/null/undefined)被真正复制
- 引用类型(对象、数组、函数)只复制其内存地址,新旧对象共享同一嵌套结构
- 若两个配置中都有
api: { timeout: 5000, baseUrl: '/v1' },后者的整个api对象会直接替换前者,不会合并timeout和baseUrl字段
适合浅拷贝合并的多层配置结构设计
把“可能被部分覆盖”的配置项拆成独立顶层键,避免嵌套冲突:
- ❌ 不推荐:
{ network: { timeout: 5000, retry: 3 }, ui: { theme: 'dark', fontSize: 14 } } - ✅ 推荐:
{ network_timeout: 5000, network_retry: 3, ui_theme: 'dark', ui_fontSize: 14 } - 这样即使用户只传
{ network_timeout: 3000 },其余字段也不会被清空或覆盖
用浅拷贝实现“伪多层”合并的常见模式
对必须保留嵌套结构的场景,可通过手动提取+合并方式绕过限制:
- 先分别浅拷贝各层级默认配置:
const baseNetwork = { ...defaults.network } - 再按需合并用户配置中的对应部分:
const finalNetwork = { ...baseNetwork, ...userConfig.network } - 最后组装顶层:
const config = { ...defaults, network: finalNetwork, ui: { ...defaults.ui, ...userConfig.ui } }
何时该果断放弃浅拷贝?
当以下任一情况出现时,说明已超出浅拷贝适用范围,应切换方案:
- 配置中大量使用嵌套对象(如
headers: { 'X-Auth': '', 'Content-Type': '' }),且要求用户能只覆盖其中某一项 - 项目已引入 Lodash,可用
_.merge()实现安全的深度合并 - 运行环境支持现代 API(Chrome 98+/Node.js 17.0+),优先用
structuredClone()配合自定义合并逻辑 - 配置来源包含不可信数据(如 JSON API 响应),需避免
JSON.parse(JSON.stringify())的序列化陷阱

















