Script Valley
JavaScript: The Complete Language
Advanced JavaScript PatternsLesson 6.4

Proxy and Reflect: intercepting JavaScript object operations

Proxy constructor, handler traps, get set has deleteProperty, Reflect API, use cases validation reactivity logging, Proxy vs Object.defineProperty, revocable proxies

Intercept Any Object Operation

A Proxy wraps an object and intercepts fundamental operations — property reads, writes, deletions, and function calls — letting you add behavior transparently without modifying the original object. Vue 3's reactivity system is built on Proxy. Many validation and logging libraries use it too.

Basic Proxy with get and set Traps

const target = { name: "Ana", age: 28 };

const proxy = new Proxy(target, {
  get(obj, key) {
    console.log(`Reading: ${key}`);
    return Reflect.get(obj, key);
  },
  set(obj, key, value) {
    if (key === "age" && typeof value !== "number") {
      throw new TypeError("age must be a number");
    }
    return Reflect.set(obj, key, value);
  }
});

proxy.name;       // logs "Reading: name", returns "Ana"
proxy.age = "x";  // throws TypeError
proxy.age = 30;   // sets age to 30

Validation Proxy Factory

function validated(obj, schema) {
  return new Proxy(obj, {
    set(target, key, value) {
      if (schema[key] && !schema[key](value)) {
        throw new Error(`Invalid value for ${key}: ${value}`);
      }
      return Reflect.set(target, key, value);
    }
  });
}

const user = validated({}, {
  age: v => typeof v === "number" && v >= 0
});
user.age = 25;  // ok
user.age = -1;  // throws Error

Why Reflect

Always use Reflect methods inside traps rather than accessing the target directly. Reflect.get(obj, key, receiver) correctly threads the receiver through inherited getters, preventing subtle bugs when prototypes are involved.

Up next

WeakMap, WeakSet, and memory management in JavaScript

Sign in to track progress