TIL
Back

JavaScript Proxy Objects

A JavaScript Proxy is an object that intercepts fundamental operations on another object, called its target. The handler supplies traps for operations such as property access, assignment, deletion, enumeration, prototype lookup, function calls, and construction.1

const observed = new Proxy(
	{ theme: "dark" },
	{
		get(target, property, receiver) {
			console.log(`read ${String(property)}`);
			return Reflect.get(target, property, receiver);
		},
	},
);

JavaScript syntax invokes internal object methods. Reading proxy.x maps to get, x in proxy maps to has, and key enumeration maps to ownKeys. Callable targets also support apply, while constructable targets support construct.

Reflect provides methods named after the traps and is the usual way to forward an operation while preserving its receiver and return value. Calling a Reflect method on the proxy from its matching trap can recurse, so forwarding normally uses the target.2

Traps must preserve the target's invariants. For example, get cannot invent a value for a non-writable, non-configurable property, and ownKeys cannot omit a non-configurable key. The engine checks these rules and throws TypeError when a trap lies.3

A proxy has its own identity and does not acquire the target's private fields or native internal slots. Proxies around classes, Map, or Set can therefore fail when a method receives the proxy as this. Interception is shallow, so nested values need separate proxies. Proxy.revocable() creates a proxy that can later be disabled.1

References

  1. MDN, “Proxy”. 2

  2. MDN, “Reflect”.

  3. ECMA International, proxy object internal methods.