JavaScript中如何不创建类实例直接获取类的所有属性?
无需实例化枚举JavaScript类声明属性的实现方案
实现原理
JavaScript原生没有提供直接读取类声明的实例属性的API,getOwnPropertyNames、hasOwnProperty、getPrototypeOf这类API都是针对对象实例生效,无法直接从类构造函数本身拿到实例字段列表。
类的所有顶层字段声明都会包含在类的toString()返回的源码文本中,我们可以通过静态解析类源码的方式,提取所有顶层声明的实例属性,完全不需要创建类实例。
完整实现代码
function getClassProperties(cls) { if (typeof cls !== 'function' || !/^class\s/.test(Function.prototype.toString.call(cls))) { throw new TypeError('传入参数必须为合法的类'); } const classSource = Function.prototype.toString.call(cls); const propSet = new Set(); // 截取类体内容,剔除class声明头部和末尾闭合括号 const classBody = classSource.slice( classSource.indexOf('{') + 1, classSource.lastIndexOf('}') ); // 匹配顶层实例属性:排除静态属性、私有属性,兼容无初始值、带初始值两种声明写法 const fieldReg = /^\s*(?!static\s)(?!#)([a-zA-Z_$][\w$]*)\s*[;=]/gm; let matchRes; while ((matchRes = fieldReg.exec(classBody)) !== null) { propSet.add(matchRes[1]); } return Array.from(propSet); }
效果验证
针对给出的示例代码,运行结果完全符合预期:
class Rectangle { height; width; constructor(width) { this.width = width; } } getClassProperties(Rectangle) // 返回 ['height', 'width']
边界说明
该方案只能提取类体中显式声明的顶层实例字段,无法识别构造函数、类方法内部动态挂载到
this上的属性。这部分属性属于运行时逻辑,在不创建实例执行对应代码的前提下,没有任何原生手段可以静态获取到这类属性名。
该实现默认做了以下过滤:
- 自动排除静态属性(
static关键字修饰的属性) - 自动排除私有属性(
#开头的属性) - 不会将构造函数、类方法误识别为实例属性
- 兼容带初始值的字段声明(比如
color = 'red'会被正确识别为color属性)
内容的提问来源于stack exchange,提问作者Ella
相关产品推荐
相关产品推荐

