JavaScript 中 class 是静态语法,但可通过工厂函数动态返回定制类,支持按配置生成属性、方法和校验逻辑,保持标准 class 特性且安全可调试。

JavaScript 的 class 本身是静态语法结构,不能像函数调用那样“动态生成类名”或“运行时拼接 class 定义”。但可以通过函数封装 + 构造逻辑 + 原型操作等方式,实现**行为上等效的动态类创建**,满足灵活配置需求——比如根据参数决定属性、方法、继承关系或验证规则。
用工厂函数返回定制 class
这是最清晰、推荐的方式:定义一个函数,接收配置项,内部返回一个动态构造的 class 表达式。
- 支持传入字段名、默认值、是否只读、校验函数等
- 生成的类仍具备标准 class 特性(可继承、有 constructor、能用 instanceof)
- 避免 eval 或字符串拼接,安全且可调试
示例:
function createEntityClass(config) {
const { name = 'Entity', fields = [], validators = {} } = config;
return class {
constructor(data = {}) {
fields.forEach(key => {
this[key] = data[key] !== undefined ? data[key] : null;
});
}
validate() {
const errors = [];
Object.entries(validators).forEach(([key, fn]) => {
if (fn(this[key])) errors.push(`${key} is invalid`);
});
return errors;
}
};
}
// 使用
const User = createEntityClass({
name: 'User',
fields: ['id', 'username', 'email'],
validators: {
email: v => !v || !v.includes('@')
}
});
const u = new User({ username: 'alice', email: 'alice@example.com' });
console.log(u.validate()); // []
动态挂载方法与属性到 prototype
若需在已有类基础上按条件添加能力(如插件机制),可在运行时修改其 prototype。
- 适合配置驱动的功能开关(例如:是否启用日志、缓存、序列化)
- 注意避免污染全局类原型;建议仅作用于你控制的类
- 方法挂载后,所有实例自动获得该能力
示例:
class ApiClient {
constructor(baseURL) {
this.baseURL = baseURL;
}
}
// 根据环境动态增强
if (process.env.DEBUG === 'true') {
ApiClient.prototype.logRequest = function(url) {
console.log('[API]', `Calling ${url}`);
};
}
const client = new ApiClient('/api');
client.logRequest('/users'); // 仅在 DEBUG 模式下存在
结合 Proxy 实现配置式对象模板
当不需要真正 class 实例,而只要一个“行为可配置的对象模板”时,Proxy 是更轻量的选择。
- 拦截 get/set/construct,实现字段校验、默认值注入、只读控制
- 无需 new,直接生成配置化对象
- 适合表单模型、配置中心、Mock 数据生成等场景
示例(简易配置对象):
function createConfigurableModel(schema) {
return new Proxy({}, {
get(target, prop) {
const def = schema[prop];
if (def && def.default !== undefined) return def.default;
return target[prop];
},
set(target, prop, value) {
const def = schema[prop];
if (def && def.readOnly) return false;
if (def && def.validator && !def.validator(value)) return false;
target[prop] = value;
return true;
}
});
}
const userSchema = {
name: { default: 'Anonymous', readOnly: false },
role: { validator: v => ['admin', 'user'].includes(v) }
};
const user = createConfigurableModel(userSchema);
user.name = 'Tom'; // ✅
user.role = 'guest'; // ❌ 不通过校验
不推荐但需了解的方式
某些场景会看到 eval 或 Function 构造器拼接 class 字符串,例如:
const className = 'Dynamic' + Date.now();
const clsCode = `class ${className} { constructor() { this.id = 1; } }`;
const DynamicClass = eval(clsCode);
⚠️ 这种方式存在严重风险:破坏代码压缩、无法被静态分析、触发 CSP 限制、难以调试。生产环境应避免。


















