object.assign本身不支持链式调用,但可通过封装返回this的构造器实现.with()、.when()、.done()等链式方法;其核心是每次操作修改同一target并返回实例,最终.done()返回结果;注意为不可变需深拷贝,深合并需lodash.merge等替代方案。

Object.assign 本身不支持链式调用,因为它只返回目标对象,而没有封装成可连续调用的方法。但你可以自己封装一个链式对象合并器,利用 Object.assign 的返回值特性(即返回修改后的目标对象)来实现流畅的 .with()、.when()、.done() 等调用风格。
链式调用的核心逻辑
关键在于:
- 每次操作都基于同一个目标对象(或新建空对象);
- 所有方法都返回
this(即当前实例),从而支持连续调用; - 最终用
.done()返回合并完成的对象。
例如:
const config = inject({ host: 'localhost' })
.with({ port: 3000 })
.when(process.env.NODE_ENV === 'prod', { ssl: true })
.done();
这背后是一个轻量级构造器,不是原生 Object.assign 的功能,而是对其的封装增强。
如何手动实现一个基础链式合并器
function inject(target = {}) {
return {
target,
with(source) {
Object.assign(this.target, source);
return this;
},
when(condition, source) {
if (condition) Object.assign(this.target, source);
return this;
},
done() {
return this.target;
}
};
}
-
.with():无条件合并; -
.when():按条件决定是否合并; -
.done():收尾并返回最终对象。
⚠️ 注意:所有操作都是可变的——原始
target对象会被持续修改。如果需要不可变语义,应在内部用{}作为初始target,或配合structuredClone(现代环境)/_.cloneDeep(兼容旧环境)做深拷贝。
处理嵌套对象与深合并需求
Object.assign 是浅拷贝,所以:
-
{ user: { name: 'A' } }和{ user: { age: 25 } }合并后,user会被整个替换,不是{ name: 'A', age: 25 }; - 若需深合并,可替换为
lodash.merge(它也返回目标对象,仍可链式):
import { merge } from 'lodash-es';
// 改写 .with() 方法:
with(source) {
merge(this.target, source);
return this;
}
或者用原生方案(如递归 Object.assign + Array.isArray 判断),但复杂度上升。
进阶:支持属性筛选与响应式注入
你还可以扩展链式 API:
-
.pick(['a', 'b']):只保留指定键; -
.omit(['c']):排除某些键; -
.reactive(cb):为属性添加 setter 监听(结合Object.defineProperty或Proxy);
这些都不依赖 Object.assign 本身,而是构建在其返回值和可变性基础上的上层能力。
不复杂但容易忽略:链式调用本质是“语法糖”,真正干活的仍是 Object.assign 或它的替代品。设计时要明确——你要的是简洁写法,还是真正的不可变、深合并、响应式等语义,再决定底层用什么机制。











