JS class 天然适配工厂模式,可通过静态方法实现类内工厂(如new this()支持继承)、独立工厂类协调多类产品(如UIFactory.create()),或结合抽象基类构建策略型工厂(如PaymentFactory.create()),辅以参数校验、一致返回值等细节提升可维护性。

JS 的 class 语法天然适合工厂模式,关键在于把“创建逻辑”从调用处抽离,交由一个集中、可复用的函数或静态方法来完成。不需要手动 new 每个类,也不暴露具体构造细节。
用静态方法做类内工厂
在 class 内部定义 static 方法,作为该类的专属工厂。它接收参数,内部调用 new this(),既复用构造逻辑,又支持继承时自动创建子类实例。
- 避免硬编码类名,比如写
new User();改用new this(),子类调用时仍生成子类实例 - 适合批量初始化:传入数组,返回多个实例
- 可嵌入数据校验、默认值填充、钩子回调等增强逻辑
示例:
class Person {<br> constructor(name, age) {<br> this.name = name;<br> this.age = age;<br> }<br> static fromList(data) {<br> return data.map(item => new this(item.name, item.age));<br> }<br>}<br><br>class Staff extends Person {<br> constructor(name, age, dept) {<br> super(name, age);<br> this.dept = dept;<br> }<br> static fromList(data) {<br> return data.map(item => new this(item.name, item.age, item.dept));<br> }<br>}<br><br>// 调用子类工厂,得到 Staff 实例<br>const team = Staff.fromList([{ name: 'Alice', age: 28, dept: 'FE' }]);
用独立工厂类协调多类产品
当需要创建不同类的实例(比如 Button、Input、Modal),可定义一个统一工厂类,用参数决定返回哪一类对象。
- 所有产品类共享接口(如都有
render()方法),工厂只关心“做什么”,不关心“怎么做” - 新增产品时,只需扩展工厂的
switch或映射表,不改动已有调用代码 - 适合 UI 组件库、配置驱动型系统
示例:
class Button { render() { return '<button>Click</button>'; } }<br>class Input { render() { return '<input type="text">'; } }<br><br>class UIFactory {<br> static create(type) {<br> switch (type) {<br> case 'button': return new Button();<br> case 'input': return new Input();<br> default: throw new Error('Unknown UI type');<br> }<br> }<br>}<br><br>const btn = UIFactory.create('button'); // 返回 Button 实例<br>console.log(btn.render()); // <button>Click</button>
结合工厂与抽象基类提升扩展性
对有共性但行为各异的一组类,先定义抽象基类(含模板方法或抽象方法),再让具体子类实现差异逻辑。工厂按需实例化子类,调用方只依赖基类接口。
- 基类声明契约(如
execute()),子类各自实现 - 工厂根据策略(如配置项、环境)选择子类
- 后续加新策略,只需新增子类 + 工厂分支,零侵入原逻辑
示例:
class PaymentStrategy {<br> execute(amount) { throw new Error('Must implement execute'); }<br>}<br><br>class Alipay extends PaymentStrategy {<br> execute(amount) { return `Alipay: ¥${amount}`; }<br>}<br><br>class WechatPay extends PaymentStrategy {<br> execute(amount) { return `Wechat: ¥${amount}`; }<br>}<br><br>class PaymentFactory {<br> static create(method) {<br> switch (method) {<br> case 'alipay': return new Alipay();<br> case 'wechat': return new WechatPay();<br> default: throw new Error('Unsupported method');<br> }<br> }<br>}<br><br>const pay = PaymentFactory.create('alipay');<br>pay.execute(99.9); // Alipay: ¥99.9
注意几个实用细节
实际使用中容易忽略但影响长期维护的点:
-
不要在静态工厂里修改原型:比如
this.prototype.xxx = ...是错的——静态方法里的this是类本身,不是原型对象 -
参数校验建议前置:在
new之前检查必填字段,避免实例创建后抛错,更利于调试 - 工厂返回值保持一致:要么总是返回单个实例,要么总是返回数组,避免调用方反复判断类型
-
异步工厂需明确标识:如果创建过程涉及加载、请求(如动态 import 组件),方法名加上
Async后缀,返回 Promise


















