# Proxy and Reflect

The **Proxy** object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object (like property lookup, assignment, enumeration, function invocation, etc.).

**Reflect** is a built-in object that provides methods for interceptable JavaScript operations. The methods are the same as those of proxy handlers.

## 1. The Proxy Object

A Proxy is created with two parameters:
*   **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 (traps).

### Basic Syntax

```javascript
const target = {
  message1: "hello",
  message2: "everyone"
};

const handler = {
  get(target, prop, receiver) {
    if (prop === "message2") {
      return "world";
    }
    return Reflect.get(...arguments);
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.message1); // "hello"
console.log(proxy.message2); // "world"
```

## 2. Traps

"Traps" are methods that provide property access. This is analogous to the concept of traps in operating systems.

Common traps include:
*   `get(target, prop, receiver)`: Intercepts reading properties.
*   `set(target, prop, value, receiver)`: Intercepts writing properties.
*   `has(target, prop)`: Intercepts the `in` operator.
*   `deleteProperty(target, prop)`: Intercepts the `delete` operator.
*   `apply(target, thisArg, argumentsList)`: Intercepts function calls.
*   `construct(target, args)`: Intercepts the `new` operator.

## 3. The Reflect Object

Reflect is a static object (like `Math`). It provides methods that correspond to the Proxy traps.

Why use `Reflect`?
1.  **Forwarding default behavior:** Inside a Proxy trap, you often want to perform the original operation after doing some custom logic. `Reflect` makes this easy.
2.  **Better return values:** `Reflect.defineProperty` returns a boolean (success/failure) instead of throwing an error like `Object.defineProperty`.

### Example: Validation with Proxy and Reflect

```javascript
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
    return Reflect.set(obj, prop, value);
  }
};

const person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
// person.age = 'young'; // Throws TypeError
// person.age = 300;     // Throws RangeError
```

## 4. Use Cases

1.  **Validation:** Ensuring data integrity before writing to an object.
2.  **Logging/Debugging:** Tracking when properties are accessed or changed.
3.  **Data Binding:** Automatically updating the UI when the model changes (Vue 3 uses Proxies for reactivity).
4.  **API Mocking:** Intercepting calls to non-existent methods.

[[programming/javascript/vanilla/javascript]]
[[programming/javascript/vanilla/es6-features]]