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

JavaScript中如何获取类实例对象的getter函数?

核心原因

你无法直接通过原型属性访问拿到getter、调用报错的本质原因:

  • class内定义的get xxx()是挂载在原型上的访问器属性,不是普通数据属性/直接挂载的方法。访问属性时JS会自动执行属性描述符中的get函数,将返回值作为属性值,无法通过属性直接拿到getter函数本身。
  • 直接访问test.__proto__.c时,get函数内的this指向Test.prototype,这个原型对象上没有你在constructor中定义的a、b实例属性,因此执行后返回undefined。
  • 访问器属性名本身不是函数引用,直接在后面加()调用自然会抛出「不是函数」的类型错误。
实现方案

要拿到实例可访问的所有getter,需要沿着原型链遍历每一层原型的自有属性描述符,筛选出带get方法的访问器属性,绑定实例作为this上下文即可使用。

注意:你提供的测试代码中get d()漏写了return关键字,执行会默认返回undefined,需要修改为get d() { return this.a + this.b; }才能得到正确计算结果。

参考实现代码:

class Test {
  constructor() {
    this.a = 1;
    this.b = 2;
  }

  get c() { return this.a; }
  get d() { return this.a + this.b; }
}

const test = new Test();
const getters = [];

// 沿原型链遍历,直到根对象Object.prototype停止
let currentProto = Object.getPrototypeOf(test);
while (currentProto && currentProto !== Object.prototype) {
  const descriptors = Object.getOwnPropertyDescriptors(currentProto);
  Object.values(descriptors).forEach(desc => {
    if (typeof desc.get === 'function') {
      // 绑定实例this后存入数组
      getters.push(desc.get.bind(test));
    }
  });
  currentProto = Object.getPrototypeOf(currentProto);
}

// 执行所有getter
getters.forEach(getter => {
  console.log(getter());
});
// 输出结果:1、3
补充说明
  • 不推荐使用非标准的__proto__属性访问原型,标准API为Object.getPrototypeOf(obj)。
  • 如果不需要获取继承自父类的getter,去掉while循环、只遍历实例的第一层原型即可。
  • 判断属性是否为getter的唯一可靠方式是检查属性描述符中是否存在get字段,无法通过属性值的类型直接判断。

内容的提问来源于stack exchange,提问作者hee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 01:42:28