Hacker News new | ask | show | jobs
by fergie 2959 days ago
You are essentially restating my question: what _are_ the possibilities with proxies? (What can you do with proxies that is much more messy/difficult/verbose to do otherwise?)
3 comments

One possibility is adding syntactic sugar to objects. I posted elsewhere in this thread about how we used them in Remote Browser, but here's a simple example of adding support for negative indexing to an array. This basically creates a shorthand for array[-n] === array[array.length - n].

    class MyArray extends Array {
      constructor(...args) {
        super(...args);
        return new Proxy(this, {
          get: (target, name) => {
            if (name && name.match && name.match(/^-\d+$/)) {
              return Reflect.get(target, this.length + parseInt(name, 10));
            }
            return Reflect.get(target, name);
          },
          set: (target, name, value) => {
            if (name && name.match && name.match(/^-\d+$/)) {
              return Reflect.set(target, this.length + parseInt(name, 10), value);
            }
            return Reflect.set(target, name, value);
          },
        });
      }
    }
You could accomplish the same thing by creating explicit setters and getters, but proxies allow you to directly intercept and modify the behavior of property access, calling an object like a function, etc. This sort of flexibility allows you to create APIs that wouldn't be possible otherwise.
I've used it to extend the functionality of a library without having to monkeypatch or subclass a bunch of classes. See here: https://github.com/StephenGrider/AdvancedNodeComplete/blob/m...

The CustomPage class 'extends' through the use of a proxy a Page and Browser class, while adding its own methods on top. The proxy mediates access to the Custompage instance, and the Page and Browser. When calling a method on CustomPage, it first looks to see if the method exists on the CustomPage instance, then the Browser instance, then the Page.

I had originally wanted to subclass Page, which is implemented by the Puppeteer library, but the Browser class had a dozen direct references to the Page class. I would have had to sublcass the Browser as well and override all those methods to instead reference my CustomPage. The proxy seemed like an appropriate solution.

You can log all property accesses on an object, e.g. for testing purposes. For example, see https://searchfox.org/mozilla-central/rev/da499aac682d0bbda5... (or at https://github.com/w3c/web-platform-tests/blob/a47dd526b9033... depending on which of these stays up more permanently).