构造函数本身不是工厂模式,因其直接调用 new 会暴露类名和实例化细节;工厂模式需通过工厂函数封装创建逻辑,统一接口、隐藏具体类型,如 createUser(role) 内部按条件调用不同构造函数并返回实例。

JavaScript 中构造函数本身不是工厂模式,但可以结合工厂函数来实现工厂模式的对象创建——核心是用工厂函数封装构造逻辑,避免直接调用 new,从而解耦对象创建过程与具体类型。
为什么构造函数不能直接算工厂模式?
工厂模式的关键特征是“将对象的创建过程封装起来,对外提供统一接口,隐藏实例化细节”。而单纯使用构造函数(如 new User())会暴露类名和 new 操作,客户端需知道具体类型,违背了工厂模式的初衷。
真正的工厂模式需要一个“中间层”——通常是普通函数或方法,它内部决定创建哪个构造函数的实例,并返回该实例。
用工厂函数封装构造函数(推荐写法)
定义多个构造函数,再用一个工厂函数根据条件选择并实例化:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先定义不同职责的构造函数(如
User、Admin、Guest) - 编写工厂函数(如
createUser(role)),内部用switch或映射表决定调用哪个构造函数 - 工厂函数统一返回实例,调用方无需关心
new或构造函数名
示例:
function User(name) { this.name = name; this.role = 'user'; }
function Admin(name) { this.name = name; this.role = 'admin'; this.permissions = ['read', 'write']; }
function Guest(name) { this.name = name; this.role = 'guest'; }
function createUser(name, role) {
switch (role.toLowerCase()) {
case 'admin': return new Admin(name);
case 'guest': return new Guest(name);
default: return new User(name);
}
}
// 使用
const user = createUser('Alice', 'user'); // User { name: 'Alice', role: 'user' }
const admin = createUser('Bob', 'admin'); // Admin { name: 'Bob', role: 'admin', permissions: [...] }
进阶:支持可配置的构造函数工厂
若构造函数参数复杂或需动态扩展,可让工厂接收构造函数引用或配置对象:
- 传入构造函数本身(增强复用性)
- 用对象配置初始化行为(如预设属性、校验逻辑)
- 返回实例前可统一处理(如日志、默认赋值)
示例:
function createInstance(Constructor, config = {}) {
const instance = new Constructor(config.name);
if (config.init) config.init(instance); // 预留钩子
return instance;
}
// 使用
const user = createInstance(User, { name: 'Charlie' });
const admin = createInstance(Admin, {
name: 'Diana',
init: inst => inst.lastLogin = new Date()
});
注意原型链与 instanceof 的兼容性
用工厂函数创建的实例,其原型链仍指向原构造函数的 prototype,因此 instanceof 和原型方法依然有效:
-
user instanceof User→ true -
admin instanceof Admin→ true - 所有实例都能正常使用构造函数原型上的方法
这意味着你既享受了工厂模式的灵活性,又保留了构造函数的原型继承优势。

















