如何在JavaScript类初始化前访问类的属性键?
解决方案
1. 动态获取类属性键进行过滤(推荐)
利用类的原型对象获取所有定义的实例属性,过滤掉constructor方法后,只保留类本身的属性键,再通过过滤后的合法数据批量赋值,无需手动维护属性列表:
class BusinessConfiguration { logoId?: string; positiveLogoId?: string; negativeLogoId?: string; faviconId?: string; primaryColor?: string; windowTabName?: string; shouldShowGDPR?: boolean; allowsTermination?: boolean; styleConfiguration?: any; shouldUseCustomTitle?: boolean; processNotesStickers?: any[]; terminationProcesses?: any[]; shouldUseCustomHeader?: boolean; completeDelete?: boolean; pingConfiguration?: any; passwordConfiguration?: any; shouldAllowRandomRepeat?: boolean; shouldRedirectImmediately?: boolean; constructor(data: Partial<BusinessConfiguration>) { if (!data) return; // 获取类的所有实例属性键(排除constructor方法) const classPropertyKeys = Object.getOwnPropertyNames(this.constructor.prototype).filter( key => key !== 'constructor' ); // 过滤data,只保留类已有的属性 const validData = Object.fromEntries( Object.entries(data).filter(([key]) => classPropertyKeys.includes(key)) ); // 批量赋值 Object.assign(this, validData); } }
优点:
- 无需手动维护属性列表,类属性更新时自动同步
- 运行时自动过滤不属于类的属性,即使data为
any类型也不会给实例添加多余属性 - 代码简洁,构造函数逻辑清晰
注意:
- 无法获取类的私有属性(以
#开头的属性),若类包含私有属性需单独处理 - 存在继承时会包含父类的实例属性,若需仅保留当前类属性,可结合
Object.getOwnPropertyNames(this)(但仅能获取已初始化默认值的属性)
2. 结合类型守卫的静态属性列表
如果需要更严格的类型控制,可以手动维护属性列表并配合TypeScript类型守卫,实现类型层面和运行时的双重校验:
class BusinessConfiguration { // 定义类属性的键数组,同时作为类型约束 static readonly PROPERTY_KEYS: Array<keyof BusinessConfiguration> = [ 'logoId', 'positiveLogoId', 'negativeLogoId', 'faviconId', 'primaryColor', 'windowTabName', 'shouldShowGDPR', 'allowsTermination', 'styleConfiguration', 'shouldUseCustomTitle', 'processNotesStickers', 'terminationProcesses', 'shouldUseCustomHeader', 'completeDelete', 'pingConfiguration', 'passwordConfiguration', 'shouldAllowRandomRepeat', 'shouldRedirectImmediately' ]; logoId?: string; positiveLogoId?: string; // ...其他属性省略 constructor(data: Partial<BusinessConfiguration>) { if (!data) return; // 类型守卫:判断键是否属于类属性 const isValidKey = (key: string): key is keyof BusinessConfiguration => { return BusinessConfiguration.PROPERTY_KEYS.includes(key as keyof BusinessConfiguration); }; Object.entries(data).forEach(([key, value]) => { if (isValidKey(key)) { this[key] = value; } }); } }
优点:
- 类型层面更严格,编辑器会提示属性键的正确性
- 运行时校验明确,可自定义过滤逻辑
缺点:
- 类属性更新时需要同步维护
PROPERTY_KEYS数组,容易遗漏
3. 简化的安全批量赋值(依赖TypeScript类型检查)
如果项目严格禁用any类型,且路由层验证足够可靠,可以直接使用Object.assign,通过TypeScript类型约束确保data仅包含类的属性:
constructor(data: Partial<BusinessConfiguration>) { if (!data) return; Object.assign(this, data); }
优点:
- 代码极简,无额外逻辑
- TypeScript编译时会检查data的属性是否属于类
缺点:
- 若data被强制转为
any类型,运行时会给实例添加多余属性,无防御能力
内容的提问来源于stack exchange,提问作者Uros Stanimirovic
相关产品推荐
相关产品推荐

