You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:06:25