The two test cases blow both pass. I simply don’t understand the behavior. It seems that JavaScript Proxy cannot trap property getting inside a getter function.
test('JS Proxy normal method', () => { class Store { hidden = false; visible() { return !this.hidden; } } const accessList: PropertyKey[] = []; const proxy = new Proxy<Store>(new Store(), { get: (target: any, propertyKey: PropertyKey) => { accessList.push(propertyKey); return Reflect.get(target, propertyKey); }, }); expect(proxy.visible()).toBe(true); expect(accessList).toEqual(['visible', 'hidden']); }); test('JS Proxy getter method', () => { class Store { hidden = false; get visible() { return !this.hidden; } } const accessList: PropertyKey[] = []; const proxy = new Proxy<Store>(new Store(), { get: (target: any, propertyKey: PropertyKey) => { accessList.push(propertyKey); return Reflect.get(target, propertyKey); }, }); expect(proxy.visible).toBe(true); expect(accessList).toEqual(['visible']); });
Advertisement
Answer
You’re missing the receiver of the property access. The property might be defined on a different object than it is accessed on, and your Reflect.get
call needs to take that into account. In particular, the receiver you get as a argument of the get
trap is the proxy itself, and that’s also the object you want to evaluate the getter against, so that its this
value refers to the proxy. However, Reflect.get(target, propertyKey)
is the same as target[propertyKey]
, where the this
value in the getter is set to the target
and the .hidden
property access can’t be detected by your proxy.