4

I understand that Proxy can be used to alter object-level behaviors, such as bracket notation get and set. All the examples I can find show constructing an object and then wrapping it with a Proxy call. Is there a way to define a class Foo, using ES6 class constructor notation, such that the returned object from the constructor is already wrapped in Proxy, rather than the caller of the constructor having to also call Proxy separately?

Thanks in advance.

Ming
  • 1,613
  • 12
  • 27
  • 1
    Yes, there is, but you probably should avoid it. Rather have a factory function (that might be a static method) that produces proxy-wrapped instances. – Bergi Jul 04 '18 at 16:09

2 Answers2

4

If I understand your question properly, what you want to do, is in the constructor return a new proxy like this:

class MyClass {
  constructor() {
    return new Proxy(this, {
      // Proxy settings here
    })
  }
}

Here in this example, we create a new class, then call a few properties. The proxy will then just print out the properties that were called for simplicity.

class MyClass {
  constructor() {
    return new Proxy(this, {
      get: (target, key) => {
        console.log('I am the key: ' + key)
        return Reflect.get(target, key)
      }
    })
  }
}

let c = new MyClass
c.awesome
c.billy
c.superTroopers

if (c instanceof MyClass) {
  console.log('I am an instance of MyClass')
} else {
  console.log('I am not an instance of MyClass')
}
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • Thanks for this! It looks like what I was originally looking for. As a follow-up: Does this work as expected with `instanceof`, or would further fiddling be necessary if that behavior is desired? – Ming Jul 04 '18 at 17:27
  • 1
    Yes it does. If you see my edits, you will see that it prints `I am an instance`. – Get Off My Lawn Jul 04 '18 at 18:07
-1

As far as I know: no, but you can set the prototype afterwards. Something like this:

class Thing {

    constructor() {
        // ...
    }

}

Thing.prototype = new Proxy(Thing.prototype, {

    get(target, name) {
        // ...
    }

});
James Long
  • 4,629
  • 1
  • 20
  • 30