JavaScript Proxy Explained: Customizing Object Behavior with Traps

Proxy generally means a substitute or intermediary. In computer networking, a proxy server acts as an intermediary between a client and the internet. In JavaScript, a Proxy object acts as an intermediary for another object, allowing you to intercept and redefine fundamental operations like property access and modification. Syntax let proxy = new Proxy(target, handler) target: the original object which you want to proxy handler: an object that defines which operations will be intercepted and how to redefine intercepted operations. MDN A trap is a method inside the handler object. A trap is a function that "traps" or intercepts a particular operation. e.g. get, set With an empty handler: The proxy acts the same way as the original object. let target = { name: "John" }; let handler = {}; let proxy = new Proxy(target, handler); console.log(proxy.name); // John proxy.age = 20; console.log(proxy.age); // 20 There are many Proxy traps, such as get(), set(), has(), and deleteProperty(). JavaScript objects have internal methods, such as [[Get]] and [[Set]], which define how fundamental operations work. Proxy traps intercept calls to these internal methods, allowing custom behavior. get(); Example: const user = { name: "John" }; console.log(user.name); // John

Apr 8, 2025 - 17:02
 0
JavaScript Proxy Explained: Customizing Object Behavior with Traps

Proxy generally means a substitute or intermediary. In computer networking, a proxy server acts as an intermediary between a client and the internet.

In JavaScript, a Proxy object acts as an intermediary for another object, allowing you to intercept and redefine fundamental operations like property access and modification.

Syntax

let proxy = new Proxy(target, handler)

target: the original object which you want to proxy
handler: an object that defines which operations will be intercepted and how to redefine intercepted operations.
MDN

A trap is a method inside the handler object. A trap is a function that "traps" or intercepts a particular operation.
e.g. get, set

With an empty handler:
The proxy acts the same way as the original object.

let target = {
    name: "John"
};

let handler = {};

let proxy = new Proxy(target, handler);

console.log(proxy.name); // John

proxy.age = 20;
console.log(proxy.age);  // 20

There are many Proxy traps, such as get(), set(), has(), and deleteProperty(). JavaScript objects have internal methods, such as [[Get]] and [[Set]], which define how fundamental operations work. Proxy traps intercept calls to these internal methods, allowing custom behavior.

get();
Example:

const user = {
    name: "John"
};

console.log(user.name); // John <-- The internal [[Get]] is used.

let proxy = new Proxy(user, {
    get(target, prop) {
        console.log(`Customised. The user's name is ${target[prop]}.`);
        return target[prop]; <-- Manually return the original property's value
    }
});

console.log(proxy.name); // Customised. The user's name is John. John

set();
The Proxy allows to custom the original object, it can be used to add a validation.

const validator = {
  set(obj, prop, value) {
    if (prop === "age") {
      if (!Number.isInteger(value)) {
        throw new TypeError("The age is not an integer");
      }
      if (value > 200) {
        throw new RangeError("The age seems invalid");
      }
    }

    // The default behavior to store the value
    obj[prop] = value;

    // Indicate success
    return true;
  },
};

const person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
person.age = "young"; // Throws an exception
person.age = 300; // Throws an exception

MDN

In a Proxy, when accessing a method, this may refer to the Proxy instead of the original object (target). The receiver argument helps control what this should be inside the method.

get(target, property, receiver);

class Person {
    constructor(name) {
        this.name = name;
    }

  greet() {
    return `Hi, ${this.name}.`;
  }
}

const person = new Person("John");
let proxy = new Proxy(person, {
  get(target, prop, receiver) {
    const value = target[prop];
    if (value instanceof Function) {
      return function (...args) {
        return value.apply(this === receiver ? target : this, args);
      };
    }
    return value;
  },
});
console.log(proxy.greet()); // Hi, John.

Proxy in JavaScript offers powerful ways to intercept and customize fundamental operations on objects. As MDN mentions, a Proxy can be used to log property accesses, validate inputs, format data, sanitize inputs, and more.