Commissioned for this museum · after Gamma, Helm, Johnson & Vlissides, 1994
Proxy
TypeScript·1994·28 lines·646 bytes
/**
* Proxy — an object standing where another would, deciding what to pass on.
*/
const engine = {
start(): string {
return "running";
},
secretKey: "hunter2",
};
// The language provides the pattern. This proxy was never told what shape
// `engine` is, and will not need telling when that shape changes.
const guarded = new Proxy(engine, {
get(target, property, receiver) {
if (property === "secretKey") {
throw new Error("not yours");
}
return Reflect.get(target, property, receiver);
},
});
console.log(guarded.start());
try {
console.log(guarded.secretKey);
} catch (error) {
console.log((error as Error).message);
}Curator’s note
Every other pattern in these two rooms is a shape you build. This one is a keyword. JavaScript grew a Proxy in 2015, and the thing the 1994 book described — an object implementing the same interface as another and choosing what to forward — became something the runtime does on your behalf.
The consequence is larger than the typing it saves. A hand-written proxy has to name every method it forwards, which means it knows the interface, which means it breaks when the interface grows: add a method to engine and a classical proxy silently lacks it. This one intercepts the *act of access* rather than any particular member, so it keeps working through changes nobody told it about. That is a different capability, not a tidier syntax, and it is why virtualisation, reactive frameworks and mocking libraries are all built on it.
The price is that the indirection is now invisible. A classical proxy is a class with a name that shows up in a stack trace and can be found by searching for it. This one is a variable that behaves exactly like the thing it wraps, right up to the moment it does not, and someone staring at guarded.secretKey throwing has nothing in the expression to tell them a proxy is involved. Vue and MobX both spend real effort making their proxies confess themselves in devtools, and that effort exists because the default is a comfortable lie.
The 1994 catalogue lists four uses — remote, virtual, protection, smart reference. This is the protection one, which is the least interesting of the four and the easiest to fit in a frame.