0

Trying to understand the internals of Proxy and Reflect built-in objects, I've reached - IMO - an interesting "how does this even work" point:

Let's say I want to wrap into a Proxy this object and detect when we're accessing a callable property:

const obj = {
 v: 42,
 foo(n) { return this.v + n }
} 
const pObj = new Proxy(obj, {
  get(target, prop, r) {
    if (typeof target[prop] === 'function') {
      console.log('accessing a function, arguments: ', { ...arguments })
    }
    return Reflect.get(...arguments);
  }
}) 

This code just works:

pObj.foo(1000) // « 1042

Printing this trace:

trace when calling the function

Which reads: arguments has

  • target ([0]): the object
  • prop ([1]): "foo"
  • receiver ([2]): the proxy object itself.

My question is, where is defined the function argument (1000) that is applied to foo(n)? isn't defined in arguments? is it possible to validate this argument before calling Reflect.get(...arguments)?

Manu Artero
  • 9,238
  • 6
  • 58
  • 73
  • You're reading the `arguments` to `get`, so it shouldn't be surprising that the arguments match those passed to `get`. I would think you'd want to use [`apply`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply) to handle a function call though. – Heretic Monkey Sep 29 '22 at 11:26
  • my point is `Reflect.get()` does call `foo(1000)` with no problems. How? Where does `1000` come from? – Manu Artero Sep 29 '22 at 11:29
  • 1
    Because `Proxy.get` is passed enough information through its arguments to allow `Reflect.get` to do its job. But you ask "Is it possible to validate this argument" and I'm saying, that's going to be a lot easier with `apply`, considering it is passed a list of arguments to the function it wraps. If you don't want that kind of practical help (using the right tool for the job), explicitly state your purpose (which could be curiosity). – Heretic Monkey Sep 29 '22 at 11:36
  • 1
    Your `get` trap executes due to the property access of `.foo` on `pObj` when you do `pObj.foo`, and not because you're calling `.foo(...)`. The `Reflect.get()` doesn't call `foo(1000)`, it returns a function (`obj.foo`), that's being invoked by `(1000)` in your original calling code outside of the proxy handler. – Nick Parsons Sep 29 '22 at 12:37
  • thanks @NickParsons, if you reply to answer I could accept this – Manu Artero Sep 29 '22 at 13:49

0 Answers0