Codectionary / Developer documentation / JavaScript

Proxy and Reflect

Proxy wraps an object and lets you intercept and customize fundamental operations on it - like getting, setting, or deleting a property - by defining "trap" functions in a handler object. Reflect provides methods that mirror those same fundamental operations, letting you forward the default behavior from inside a Proxy trap rather than reimplementing it manually.

Syntax

new Proxy(target, handler)
Reflect.get(target, key)

Examples

Basic Proxy with a get Trap

Intercepting property access to add custom behavior, like logging or defaults.

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

const loggedUser = new Proxy(user, {
  get(target, prop) {
    console.log(`Reading property: ${prop}`);
    return Reflect.get(target, prop); // forwards to the default behavior
  }
});

console.log(loggedUser.name);
// "Reading property: name"
// "Alice"

Validation with a set Trap

Using a Proxy to enforce rules whenever a property is assigned.

const validatedUser = new Proxy({}, {
  set(target, prop, value) {
    if (prop === "age" && typeof value !== "number") {
      throw new TypeError("age must be a number");
    }
    return Reflect.set(target, prop, value);
  }
});

validatedUser.age = 30; // works fine
// validatedUser.age = "old"; // throws TypeError

Default Values with a has and get Trap

Providing a fallback value for any property that does not exist.

function withDefault(obj, defaultValue) {
  return new Proxy(obj, {
    get(target, prop) {
      return prop in target ? target[prop] : defaultValue;
    }
  });
}

const settings = withDefault({ theme: "dark" }, "not set");
console.log(settings.theme);    // "dark"
console.log(settings.fontSize); // "not set" - property does not exist, but no error

Best practices

  • Use Reflect methods inside Proxy traps to forward default behavior, rather than manually reimplementing property access logic
  • Reach for Proxy for cross-cutting concerns like validation, logging, or reactivity systems - not as a general-purpose object wrapper for everyday code
  • Be aware that Proxy adds a small performance overhead on every intercepted operation - avoid it in performance-critical hot paths
  • Document any Proxy-based behavior clearly, since intercepted objects can behave in ways that are surprising to someone reading the code without that context

At a glance

Purpose
Application logic and interaction
File extension
.js ยท .mjs
Runs in
Browsers and JavaScript runtimes
Usually used with
HTML, CSS and Web APIs

Specifications & further reading

Related JavaScript documentation