ES6 class 本身不提供属性类型校验,但可通过 Proxy 包裹实例,在 set/get 中动态校验类型、转换值或控制访问;需结合静态 schema、基类封装或工厂函数复用逻辑,并注意性能与私有字段限制。

ES6 的 class 本身不提供属性类型校验或拦截机制,但可以通过 Proxy 包裹实例、结合 Reflect 和自定义校验逻辑,在运行时实现动态类型校验与赋值/取值拦截。
用 Proxy 拦截实例属性访问
不能直接在 class 内部“声明式”校验属性,但可在实例化后用 Proxy 封装,统一控制 get / set 行为:
- set 拦截:检查赋值类型是否符合预期(如 number、string、特定类实例),不符合则抛错或静默处理
- get 拦截:可做读取前转换(如自动转字符串)、权限控制或惰性计算
- 需将原始对象(this)作为
target,避免代理丢失 class 原型方法
配合元数据或装饰器声明校验规则(需额外支持)
ES6 原生不支持装饰器,但可用约定方式(如静态 schema 对象)描述字段类型,并在 Proxy 中读取:
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
static schema = {
name: String,
age: Number
};
}
const proxied = new Proxy(new User('Alice', 30), {
set(target, key, value) {
const expectedType = target.constructor.schema?.[key];
if (expectedType && !(value instanceof expectedType || typeof value === expectedType.name.toLowerCase())) {
throw new TypeError(`Expected ${key} to be ${expectedType.name}, got ${typeof value}`);
}
Reflect.set(target, key, value);
return true;
}
});
封装成可复用的基类或工厂函数
避免每个类重复写 Proxy 逻辑,可抽象为:
立即学习“Java免费学习笔记(深入)”;
- 带校验的基类:子类继承后自动获得类型检查能力(通过构造时返回代理实例)
-
工厂函数:如
createValidatedClass(Class, schema),返回增强后的构造函数 - 注意:Proxy 实例的
instanceof仍有效,只要getPrototypeOf正确返回原 prototype
注意边界与性能权衡
Proxy 是运行时拦截,无法替代 TypeScript 编译期检查,但适合需要动态策略(如配置驱动校验、API 响应字段验证)的场景:
- 对高频读写属性,Proxy 开销略高于普通属性访问,敏感场景可加缓存或仅对关键字段拦截
- 无法拦截未声明属性的首次赋值(除非用
defineProperty预设 +preventExtensions) - 私有字段(#field)无法被 Proxy 拦截,需改用 WeakMap 存储或公开字段+约定命名


















