工厂函数替代 new 的核心是将对象创建变为可复用、可配置、可测试的纯函数逻辑,避免 this 绑定、silent bug 和原型依赖,天然适配组件化与测试。

工厂函数替代 new 关键字,核心不是“省几行代码”,而是把对象创建从语法负担变成可复用、可配置、可测试的逻辑。它不强制你写 class 或处理 this 绑定,也不依赖原型链,直接返回干净的对象,天然适配前端组件化场景。
用纯函数封装创建过程,避免 new 和 this 纠缠
构造函数必须搭配 new 使用,否则 this 指向错误,容易出 silent bug;而工厂函数是普通函数,调用即得对象,语义清晰、容错性强。
- 不需记忆是否加 new:createButton() 比 new Button() 更直觉
- 无需处理 this 绑定问题:内部不依赖 this,避免箭头函数绕弯或 bind 调用
- 返回值明确可控:总是返回一个新对象,不会因忘记 new 导致意外全局污染
按需注入配置,一次定义、多处定制
工厂函数接收参数,能动态决定组件结构、默认 props、甚至行为逻辑,比写多个 class 更轻量。
- 例如 createInput({ type: 'email', required: true }) 自动添加验证逻辑和样式类
- 同一工厂可产出不同变体:createModal({ size: 'sm' }) 与 createModal({ size: 'lg', closable: false })
- 支持默认值 + 合并策略,减少重复配置代码
解耦实例化与使用,便于单元测试和替换实现
业务代码只调用工厂函数,不关心内部是 new 还是 Object.assign 还是缓存复用。这为 mock、打桩、A/B 实验留出空间。
- 测试时可直接替换整个工厂函数,返回预设 stub 对象
- 无需 sinon.stub 构造函数,避免 Jest 中对 new 的特殊处理(如 mockImplementationOnce)
- 组件库升级时,只需改工厂内部实现,调用方零改动
配合模块导出,天然支持 tree-shaking 和按需加载
工厂函数可单独导出,不带 class 声明和原型方法,体积更小;也可结合动态 import 封装异步创建逻辑。
- export const createDatePicker = () => ({ render() { /* 内联模板 */ } })
- 异步工厂:async function createHeavyChart(config) { const { Chart } = await import('./chart.js'); return new Chart(config); }
- ESM 下,未使用的工厂函数更容易被打包工具剔除

















