Labs ICT
Pro Login

Proxy Patterns

What is a Proxy?

A Proxy wraps an object and intercepts operations on it — like reading properties, setting values, or calling functions. You define "traps" that run when these operations happen. This lets you add custom behavior to any object.

const user = { name: "Alice", age: 25 };

const proxy = new Proxy(user, {
  get(target, prop) {
    console.log(`Reading "${prop}"`);
    return target[prop];
  },
  set(target, prop, value) {
    console.log(`Setting "${prop}" to ${value}`);
    target[prop] = value;
    return true;
  },
});

proxy.name;        // Logs: Reading "name"
proxy.age = 26;    // Logs: Setting "age" to 26

Common Traps

There are 13 different traps you can define. The most commonly used ones are get, set, has, and deleteProperty.

const handler = {
  get(target, prop, receiver) {},     // Intercept property reads
  set(target, prop, value, receiver) {}, // Intercept property writes
  has(target, prop) {},               // Intercept 'in' operator
  deleteProperty(target, prop) {},    // Intercept delete
  apply(target, thisArg, args) {},    // Intercept function calls
  construct(target, args) {},         // Intercept new operator
};

Practical Example: Validation

Proxies are great for data validation. You can prevent invalid values from being set on an object.

function createValidatedUser(data) {
  return new Proxy(data, {
    set(target, prop, value) {
      if (prop === "age" && (typeof value !== "number" || value < 0)) {
        throw new Error("Age must be a positive number");
      }
      if (prop === "email" && !value.includes("@")) {
        throw new Error("Invalid email");
      }
      target[prop] = value;
      return true;
    },
  });
}

const user = createValidatedUser({ name: "Alice", age: 25 });
user.age = 30;     // OK
user.age = -5;     // ❌ Error: Age must be a positive number
Try it Yourself →

Reactive Data with Proxies

Frameworks like Vue 3 use proxies under the hood to make data reactive. When you change a property, the proxy notifies any watchers to update the UI.

function reactive(obj, onUpdate) {
  return new Proxy(obj, {
    set(target, prop, value) {
      target[prop] = value;
      onUpdate(prop, value);
      return true;
    },
  });
}

const state = reactive({ count: 0 }, (prop, value) => {
  console.log(`${prop} changed to ${value}`);
  document.querySelector("#count").textContent = value;
});

state.count = 1; // Logs: count changed to 1

Summary

Proxies intercept and customize operations on objects. Use them for validation, logging, reactive data, and access control. They're a powerful metaprogramming tool in JavaScript.