ES6扩展运算符合并配置时按“从左到右、后写覆盖前写”优先级处理同名属性,仅浅层覆盖、不递归合并嵌套对象,新增属性自动添加,深层合并需手动展开或借助工具函数。

ES6 扩展运算符在配置项合并中默认按“从左到右、后写覆盖前写”的顺序处理同名属性,这是它的天然优先级规则,无需额外配置。
配置合并的基本覆盖逻辑
当使用 {...defaultConfig, ...userConfig} 合并对象时,右侧对象的属性会直接覆盖左侧同名属性。这种覆盖是浅层、按键名逐个进行的,不递归深入嵌套结构。
- 如果
userConfig中有theme: 'dark',而defaultConfig中是theme: 'light',最终结果一定是theme: 'dark' - 新增属性(如
showSidebar: true)会被自动添加进新对象,不影响原有字段 - 若多个配置对象都含同一键(如
{...a, ...b, ...c}),则c的值最终生效,a和b中该键被忽略
处理嵌套配置的常见误区
扩展运算符只做一层展开,对嵌套对象(如 api: { baseUrl: '', timeout: 5000 })不会自动深度合并——它会用整个新对象直接替换旧对象,而不是合并内部字段。
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
- 错误示例:
const final = { ...default, ...user };
若user.api是一个完整新对象,default.api.timeout等未在user.api中声明的字段将丢失 - 正确做法:对嵌套层级单独展开,或改用
Object.assign配合手动合并逻辑const final = { ...default, ...user, api: { ...default.api, ...user.api } };
需要更高控制力时的替代方案
当业务要求更精细的覆盖策略(如“仅覆盖非空值”“数组追加而非替换”“深层合并”),扩展运算符本身无法满足,需组合其他手段:
- 用
Object.assign+ 条件判断构建定制逻辑:Object.assign({}, default, Object.keys(user).reduce((acc, k) => user[k] !== undefined ? { ...acc, [k]: user[k] } : acc, {})) - 借助工具函数(如 Lodash 的
merge)实现真正深合并 - 封装一个配置合并器,支持策略参数:
mergeConfigs(default, user, { deep: true, skipFalsy: true })
React 中 className 等特殊属性的合并注意点
在 JSX 中使用扩展运算符传递 props(如 <Button {...props} />),若同时显式写 className,显式值会覆盖 spread 进来的 className —— 因为 React 的 prop 优先级规则是:显式声明 > spread props。
- 安全写法:
<Button className={`${props.className || ''} my-btn`} {...props} /> - 避免冲突:
const { className, ...rest } = props;再分别处理

















