Object.assign实现默认值混入的核心是将默认配置作为第一个参数、实际数据作为后续参数,从左到右覆盖属性;需以空对象{}为第一参数避免修改原对象,但仅支持浅拷贝。

用 Object.assign 给对象设置默认值,核心是“把默认配置作为第一个参数,实际数据作为后续参数”,它会从左到右依次覆盖属性,从而实现安全、简洁的默认值混入。
默认值优先,实际值后置
这是最关键的调用顺序。把空对象或默认配置放在第一位,要合并的数据放后面:
const defaults = { theme: 'light', fontSize: 14, autoSave: true };
const userConfig = { theme: 'dark', fontSize: 16 };
const finalConfig = Object.assign({}, defaults, userConfig);
// → { theme: 'dark', fontSize: 16, autoSave: true }
注意:第一个参数必须是新对象(如 {}),否则会直接修改 defaults 原对象。
支持多层覆盖与动态组合
可以一次合并多个来源,比如基础默认值 + 环境配置 + 用户输入:
- 环境配置(如 dev/staging/prod)可覆盖部分默认项
- 用户传入的选项再做最终覆盖
- 所有层级都只影响自身存在的 key,不干扰其他字段
const base = { timeout: 5000, retries: 3 };
const env = process.env.NODE_ENV === 'prod' ? { timeout: 3000 } : {};
const input = { retries: 5 };
const options = Object.assign({}, base, env, input);
// prod 环境下:{ timeout: 3000, retries: 5 }
注意浅拷贝限制
Object.assign 只做一层属性复制,嵌套对象不会被递归合并:
- 如果
defaults.nested和userConfig.nested都是对象,后者会整个替换前者 - 需要深层合并时,应改用
structuredClone+ 递归函数,或第三方库如 Lodash 的merge
const defaults = { api: { url: '/v1', timeout: 1000 } };
const user = { api: { url: '/v2' } };
const result = Object.assign({}, defaults, user);
// → { api: { url: '/v2' } } —— timeout 丢失了
替代写法:解构赋值更现代(但有差异)
ES6 解构也可设默认值,语法更简洁,但适用场景不同:
- 适合函数参数解构:
function init({ theme = 'light', fontSize = 14 } = {}) { ... } - 不适用于运行时动态合并已有对象字面量
- 无法保留未声明的额外属性(解构会丢弃)
所以当你要“融合两个完整对象并保留所有键”时,Object.assign 仍是直接可靠的选择。











