JavaScript Proxy and Reflect: Metaprogramming That Actually Pays Off
Proxies intercept fundamental operations on objects. Here are the patterns where metaprogramming earns its complexity. Proxy lets you define custom behavior for fundamental operations on an object, like property access, assignment, and enumeration. It is the most powerful metaprogramming feature in JavaScript, and with that power comes complexity that can hurt readability. I reach for Proxy only in specific situations where the abstraction it enables is clearly worth the indirection. The Anatomy of a Proxy A Proxy takes a target object and a handler. The handler is an object whose optional methods, called traps, intercept specific operations. The get trap intercepts property reads, the set trap intercepts assignments, has intercepts the in operator, and so on. There are thirteen traps covering operations from property access to function invocation. const handler = { get(target, key) { console.log('read', key); return Reflect.get(target, key); } }; const p = new Proxy({ a: 1 }, handler); p.a; // logs 'read a', returns 1 Reflect Pairs with Proxy The Reflect object exposes the same operations that Proxy traps intercept, as plain functions. The convention is to call Reflect.get inside a get…