Proxy in JavaScript

Introduction

A Proxy wraps an object and intercepts operations—reads, writes, deletes, and more—through traps. Proxies enable validation layers, reactive state, and API mocks. They are advanced; use plain objects unless you need interception.

Prerequisites

Basic get and set Traps

javascript
const target = { balance: 100 };
 
const account = new Proxy(target, {
  get(obj, prop) {
    console.log("read", prop);
    return Reflect.get(obj, prop);
  },
  set(obj, prop, value) {
    if (prop === "balance" && value < 0) {
      throw new Error("balance cannot be negative");
    }
    return Reflect.set(obj, prop, value);
  },
});
 
console.log(account.balance);
account.balance = 150;

Always forward to Reflect in traps unless you intentionally change behavior.

Default Forwarding Proxy

javascript
// Log only; pass through everything else
function loggingProxy(obj) {
  return new Proxy(obj, {
    get(t, key, receiver) {
      const value = Reflect.get(t, key, receiver);
      console.log("GET", String(key), value);
      return value;
    },
  });
}
 
const user = loggingProxy({ name: "Lin" });
console.log(user.name);

has and deleteProperty

javascript
const secrets = { public: 1, _hidden: 2 };
 
const safe = new Proxy(secrets, {
  has(obj, key) {
    if (String(key).startsWith("_")) return false;
    return Reflect.has(obj, key);
  },
});
 
console.log("public" in safe);
console.log("_hidden" in safe);

Revocable Proxy

javascript
// Disable proxy later
const { proxy, revoke } = Proxy.revocable({ a: 1 }, {});
 
console.log(proxy.a);
revoke();

Useful for temporary access grants.

Warning

Proxies add overhead and can confuse debuggers. Prefer simple validation functions in small projects.

Mini Example: Typed Field Guard

javascript
function createValidated(schema) {
  return new Proxy({}, {
    set(obj, prop, value) {
      const type = schema[prop];
      if (type && typeof value !== type) {
        throw new TypeError(`${String(prop)} must be ${type}`);
      }
      return Reflect.set(obj, prop, value);
    },
  });
}
 
const row = createValidated({ id: "number", title: "string" });
row.id = 1;
row.title = "Pen";
console.log(row);

FAQ

Proxy vs Object.defineProperty?

Descriptors lock individual properties; proxies intercept all operations on the object.

Can I proxy arrays?

Yes—array index access uses get/set traps with string keys "0", "1", etc.

Transparent proxies?

Possible but subtle—most patterns expose the proxy directly to consumers.

What comes next?

Web programming fundamentals.