Photo by Eric Er on Unsplash

On this page

This chapter follows QuickTip: Freezing and sealing objects.

Proxy lets you define a handler with traps that run when code interacts with a target object. Frameworks use proxies for reactivity (Vue 3, some state libraries) and for defensive wrappers around untrusted data.

Basic get and set traps

const target = { count: 0 };
const observed = new Proxy(target, {
get(obj, prop, receiver) {
return Reflect.get(obj, prop, receiver);
},
set(obj, prop, value, receiver) {
console.log('set', prop, value);
return Reflect.set(obj, prop, value, receiver);
},
});
observed.count = 1;

Traps must preserve invariants for non-configurable properties and Array length; violating them throws TypeError.

Reflect

Reflect provides the same operations as the language builtins (Reflect.get, Reflect.set, Reflect.has, Reflect.defineProperty, …) with a uniform return style—especially Reflect.set returning a boolean instead of throwing in some edge cases.

Using Reflect.* inside traps forwards default behavior and keeps receiver correct for getters that depend on this.

Common use cases

  • Validation: reject invalid assignments in a set trap.
  • Defaults: return a stand-in from get when the key is missing.
  • Revocable proxies: Proxy.revocable returns { proxy, revoke } to cut off access later—handy for capability security patterns.

Proxies add overhead; use them at boundaries (API clients, state trees), not on every plain object in a hot loop.

That completes the Objects and Classes series. For how functions close over object state, see Scope and closures.

Search articles

Type a word to search published articles.

Open the search page