工厂函数可安全调用构造函数创建实例,既保留类型识别与原型复用,又隐藏创建细节;典型写法如createuser根据role返回不同user实例,且instanceof user为true;进阶模式可返回动态构造函数。

构造函数本身不直接“在工厂模式中被包装”,但工厂函数可以内部调用构造函数来创建实例,从而融合两者优势:既保留类型识别和原型复用能力,又隐藏创建细节、支持条件逻辑或配置封装。
工厂函数里调用构造函数是常见且安全的做法
工厂函数本质是普通函数,它可以自由决定返回什么。只要内部使用 new 正确调用构造函数,就能获得具备完整构造器语义的实例(如 instanceof 有效、方法可挂载到原型上)。
- 构造函数专注定义对象结构和行为
- 工厂函数专注控制“何时创建、创建哪种、传什么参数”
- 二者分工清晰,不冲突
典型写法:工厂函数封装构造函数调用
例如根据角色类型返回不同用户实例:
function User(name, age) {
this.name = name;
this.age = age;
}
User.prototype.greet = function() {
return `Hi, I'm ${this.name}`;
};
function createUser(role, name, age) {
if (role === 'admin') {
const user = new User(name, age);
user.role = 'admin';
user.permissions = ['read', 'write', 'delete'];
return user;
} else if (role === 'guest') {
const user = new User(name, age);
user.role = 'guest';
user.permissions = ['read'];
return user;
}
}
这样创建的对象仍是 User 实例:createUser('admin', 'Alice', 30) instanceof User 返回 true,且共享 greet 方法。
注意避免常见陷阱
- 不要在工厂里漏掉 new —— 写成
User(name, age)会导致this指向错误,属性挂到全局或报错 - 不要让工厂函数直接返回构造函数本身(如
return User),这没意义;要返回的是实例 - 如果构造函数需要防御调用方式(防止忘记
new),可在内部用new.target判断,但这对工厂调用无影响,因工厂内已明确用了new
进阶:工厂返回构造函数(即“构造函数工厂”)
还有一种更灵活的模式:工厂不返回实例,而是返回一个**新构造函数**,适用于动态生成类行为:
function createPersonConstructor(prefix) {
return function Person(name, age) {
this.id = prefix + '-' + Date.now();
this.name = name;
this.age = age;
};
}
const Student = createPersonConstructor('STU');
const Teacher = createPersonConstructor('TEA');
const s1 = new Student('Tom', 20); // { id: 'STU-1728701520000', name: 'Tom', age: 20 }
const t1 = new Teacher('Lisa', 35); // { id: 'TEA-1728701520001', name: 'Lisa', age: 35 }
这种写法把构造函数也当作可配置的产出物,适合插件系统、领域模型抽象等场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











