用展开运算符合并配置的核心是“默认配置 + 用户配置”的浅层安全覆盖:先定义不可变默认对象,再按序展开默认值与用户配置,后者字段覆盖前者;嵌套对象需单独展开合并,避免污染源或误用数组/特殊类型。

用展开运算符(...)初始化带默认值的配置对象,核心是“默认配置 + 用户配置”的安全合并——它天然支持浅层覆盖,避免意外修改原始默认项。
准备不可变的默认配置
把默认值定义为常量对象,确保不被后续操作污染:
const DEFAULT_CONFIG = {
timeout: 5000,
retries: 3,
headers: { 'Content-Type': 'application/json' },
enabled: true
};
注意:如果默认值中包含对象(如 headers),展开运算符只做浅拷贝;若需深层默认,得配合其他方案(如结构化克隆或专用合并函数)。
用展开运算符合并用户传入的配置
在函数参数或初始化逻辑中,按顺序展开默认值和用户配置,后者字段会自动覆盖前者:
function createClient(userConfig = {}) {
return {
...DEFAULT_CONFIG,
...userConfig
};
}
// 示例调用
createClient({ timeout: 10000, retries: 1 });
// → { timeout: 10000, retries: 1, headers: { 'Content-Type': 'application/json' }, enabled: true }
- 用户未传的字段(如
enabled)保留默认值 - 用户传了
headers对象,会整个替换默认的headers,不是合并内部属性 - 传入
null或undefined时,...userConfig不报错(会被忽略),所以加= {}更稳妥
处理嵌套对象的常见需求
若需合并嵌套字段(如只改 headers.Authorization 而保留其他 header),展开运算符本身做不到,但可组合使用:
function createClient(userConfig = {}) {
const { headers: userHeaders = {}, ...rest } = userConfig;
return {
...DEFAULT_CONFIG,
...rest,
headers: {
...DEFAULT_CONFIG.headers,
...userHeaders
}
};
}
这种写法把 headers 单独拎出来做一层展开合并,兼顾灵活性与安全性。
避免常见陷阱
-
别直接修改默认对象:不要写
Object.assign(DEFAULT_CONFIG, userConfig),会污染默认源 - 注意数组不是对象:对数组用展开运算符是拼接,不是“覆盖默认项”,配置对象场景中一般不适用
- 函数或 Symbol 值不会被遍历:展开只复制可枚举自有属性,方法或 Symbol 键需单独处理

















