如何用ES6 Proxy捕获ES6 getter的属性访问?
问题原因与修复方案
原因分析
通过Proxy访问ageIn10Years2这个getter属性时,getter函数执行时的this指向原始的Person实例,而非Proxy对象。因此getter内部访问this.ageNow时,是直接读取原始实例的属性,不会经过Proxy的get拦截逻辑,自然不会打印ageNow。
而普通方法ageIn10Years1()的情况不同:调用peter.ageIn10Years1()时,先通过Proxy获取到方法,由于peter是Proxy对象,方法调用时内部的this会指向Proxy,访问this.ageNow会触发Proxy的get陷阱,从而打印ageNow。
修复方案
在Proxy的get陷阱中,判断当前获取的属性是否为访问器属性(getter)。如果是,手动调用getter并将this绑定到Proxy对象,确保getter内部的this指向Proxy,让属性访问经过拦截逻辑。
修改后的代码如下:
class Person { public ageNow: number; public constructor(ageNow: number) { this.ageNow = ageNow; const proxy = new Proxy(this, { get: (target, property) => { console.log(property); // 获取属性描述符,判断是否为访问器属性 const descriptor = Object.getOwnPropertyDescriptor(target, property); if (descriptor && typeof descriptor.get === 'function') { // 绑定this到proxy后调用getter return descriptor.get.call(proxy); } // 普通属性或方法,直接返回 const value = target[property as keyof typeof target]; // 给方法绑定this到proxy,确保任何调用场景下this都指向proxy if (typeof value === 'function') { return value.bind(proxy); } return value; }, }); return proxy; } public ageIn10Years1() {return this.ageNow + 10;} public get ageIn10Years2() {return this.ageNow + 10;} }
测试验证:
const peter = new Person(18); console.log(peter.ageIn10Years2);
此时会依次打印ageIn10Years2、ageNow和28,符合预期。
额外给普通方法添加bind(proxy)处理,是为了确保方法无论以何种方式调用(比如被单独提取出来调用),内部的this都指向Proxy,保证拦截逻辑始终生效。
内容的提问来源于stack exchange,提问作者Remirror
相关产品推荐
相关产品推荐

