Lusitos Tech Blog

JavaScript Proxy Object

My head as a vector graphic

Need to provide an object without knowing which operations are applied to it and without writing them manually? No problem with JavaScript Proxy Object!

Problem

You want to provide an object and you don't know beforehand which operations will be applied on it? Or maybe you know which operations, but to write every single operation manually would be way too time consuming? By operations I mean e.g. reading, writing, deleting, instantiating (new), calling, enumerating, examining, etc.

Solution

With the JavaScript (ES6) Proxy object, you can define so-called handlers (sometimes called traps) for all operations that can be performed on an object. In these handlers, you can intercept the actual request and implement your own logic. As you can see, a JavaScript proxy object has nothing to do with a network proxy.

Example

A target and a handler object are passed to the proxy constructor. The functions in the handler object receive the target as the first parameter and possibly further parameters depending on the type. So, we have a strict separation between data and logic. Each of the following functions is optional:

// It's a Trap!
const handlers = {
    getPrototypeOf(target) { /* ... */ },
    setPrototypeOf(target, v) { /* ... */ },
    isExtensible(target) { /* ... */ },
    preventExtensions(target) { /* ... */ },
    getOwnPropertyDescriptor(target, p) { /* ... */ },
    has(target, p) { /* ... */ },
    get(target, p, receiver) { /* ... */ },
    set(target, p, value, receiver) { /* ... */ },
    deleteProperty(target, p) { /* ... */ },
    defineProperty(target, p, attributes) { /* ... */ },
    enumerate(target) { /* ... */ },
    ownKeys(target) { /* ... */ },
    apply(target, thisArg, argArray) { /* ... */ },
    construct(target, argArray, newTarget) { /* ... */ },
}
const data = { foo: 'bar' };
const proxy = new Proxy(data, handlers);

Possible Applications:

  • Creating mocks in the field of unit testing
  • Uncomplicated access to databases, or translating from one API to another
  • Performing an operation on multiple objects (distribution principle)
  • Logging, caching, data validation, read-only access, side effects, ...

Further Aspects

This post was originally published here.