Proxy & Reflect

Intercept the fundamental operations on an object -- reads, writes, has, delete -- and forward them cleanly.

Syntaxnew Proxy(target, { get, set, has }); Reflect.get(target, key, receiver)

A Proxy wraps a target object and lets you intercept its basic operations via traps: get, set, has, deleteProperty, apply, and more. It is metaprogramming: you customise what property access itself means.

const safe = new Proxy(target, {
  get(obj, key) {
    if (!(key in obj)) throw new Error(`no such key: ${String(key)}`);
    return obj[key];
  },
});

Reflect is the matching toolkit

Reflect exposes those same internal operations as plain functions -- Reflect.get, Reflect.set, Reflect.has. Inside a trap you call the corresponding Reflect method to perform the default behaviour correctly, including proper this and return values.

Real uses

Reactive frameworks (Vue 3), validation layers, negative array indexing, default-value objects, access logging, and API mocks are all built on proxies.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Log every property access on a configuration object using a get trap to debug unexpected reads.
  • Validate that only numbers are set on a numeric data store using a set trap that throws on invalid input.
  • Build a reactive data model where any property change automatically triggers a UI re-render callback.

More examples

Proxy get trap for logging

The get trap intercepts every property read, logs it, and forwards the call to the real object with Reflect.get.

Example · js
const obj = { name: "Alice", age: 30 };
const proxy = new Proxy(obj, {
  get(target, key) {
    console.log("Read:", key);
    return Reflect.get(target, key);
  }
});
console.log(proxy.name); // logs "Read: name" then "Alice"

Proxy set trap for validation

The set trap validates that every assigned value is a number before forwarding it with Reflect.set.

Example · js
const nums = new Proxy({}, {
  set(target, key, value) {
    if (typeof value !== "number") throw new TypeError("Numbers only");
    return Reflect.set(target, key, value);
  }
});
nums.x = 42;     // ok
// nums.y = "hi"; // TypeError: Numbers only

Reactive proxy triggers callback

Wraps a data object in a Proxy that calls an onChange callback whenever any property is updated.

Example · js
function reactive(data, onChange) {
  return new Proxy(data, {
    set(target, key, value) {
      const result = Reflect.set(target, key, value);
      onChange(key, value);
      return result;
    }
  });
}
const state = reactive({ count: 0 }, (k, v) => console.log(`${k} changed to ${v}`));
state.count = 1; // "count changed to 1"

Discussion

  • Be the first to comment on this lesson.
Proxy & Reflect — JavaScript | SoundsCode