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
相关产品推荐
相关产品推荐

