Suggest an editImprove this articleRefine the answer for “Proxy and the get and set traps”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`Proxy` is a wrapper around an object or a function that intercepts operations on it: reading, writing, calling and so on.** You create it with `new Proxy(target, handler)`, where `target` is the original object and `handler` is an object of traps, that is, interceptor methods. The `get(target, prop, receiver)` trap fires when a property is read and decides what to return: the real value, a default, or a computed property. The `set(target, prop, value, receiver)` trap fires on assignment: it can validate data, forbid the write or trigger a side effect, and it must return `true` when the write succeeded. ```javascript const proxy = new Proxy({ name: 'Tim' }, { get: (target, prop) => target[prop] ?? 'No such property', }); proxy.age; // 'No such property' ``` **Key point:** `get` intercepts reading a property, `set` intercepts writing one and must return `true`.Shown above the full answer for quick recall.Answer (EN)Image**`Proxy` is a wrapper around an object (or a function) that intercepts operations on it: reading, writing, calling and so on.** The proxy sits between the object and the code that uses it, and decides by itself how to react to each operation. ## Theory ### TL;DR - Syntax: `new Proxy(target, handler)`. - `target` is the original object we want to work with. - `handler` is an object of traps, special interceptor methods that describe how to react to different operations. - `get` intercepts reading a property, `set` intercepts writing one. - Proxies let you log access, validate data, build reactive objects and hide private fields. - The `set` trap must return `true`, otherwise strict mode throws a `TypeError`. ### Quick example ```javascript const proxy = new Proxy(target, handler); ``` - `target` is the original object (the one we want to work with); - `handler` is an object of traps, special interceptor methods that describe how to react to different operations. ### What proxies are for Proxies let you step into the basic behaviour of objects, for example: - log access to properties; - validate data on write; - create reactive objects (this is exactly how it works in Vue); - load values lazily; - protect private data. An example, logging every access to an object: ```javascript const user = { name: 'Tim', age: 25 }; const proxy = new Proxy(user, { get(target, prop) { console.log(`Reading property "${prop}"`); return target[prop]; } }); console.log(proxy.name); // log: Reading property "name" ``` ### What the `get` trap does `get(target, prop, receiver)` fires when a property of the object is accessed: ```javascript proxy.name; proxy['age']; ``` It lets you: - control what is returned on read; - substitute default values; - build computed properties; - hide particular fields. Example: ```javascript const user = { name: 'Tim' }; const proxy = new Proxy(user, { get(target, prop) { if (prop === 'greet') { return `Hello, ${target.name}!`; } return target[prop] ?? 'No such property'; } }); console.log(proxy.name); // 'Tim' console.log(proxy.greet); // 'Hello, Tim!' console.log(proxy.age); // 'No such property' ``` ### What the `set` trap does `set(target, prop, value, receiver)` fires when we assign a value: ```javascript proxy.age = 30; ``` It lets you: - validate the new data; - forbid a write; - change values automatically; - trigger side effects (reactivity, logging and so on). Example: ```javascript const user = {}; const proxy = new Proxy(user, { set(target, prop, value) { if (prop === 'age' && typeof value !== 'number') { throw new TypeError('Age must be a number!'); } target[prop] = value; console.log(`Property "${prop}" is set to ${value}`); return true; // you must return true when everything went fine } }); proxy.age = 25; // log: Property "age" is set to 25 proxy.name = 'Tim'; proxy.age = 'a lot'; // TypeError ``` ### Summary | Component | Purpose | | --- | --- | | `Proxy(target, handler)` | Creates a wrapper around an object | | `target` | The original object | | `handler` | The object of traps (interceptor methods) | | `get` | Intercepts reading a property | | `set` | Intercepts writing a property | ### Common mistakes - **Forgetting `return true` in the `set` trap.** In strict mode, and therefore in modules, a failed assignment throws a `TypeError`. - **Thinking the proxy changes the original object.** Only operations that go through the proxy are intercepted; direct access to `target` bypasses the traps entirely. - **Forgetting that `prop` can be a symbol.** A `prop === 'age'` comparison will never match a `Symbol` key, so check the key type when it matters. - **Writing `target[prop]` instead of `Reflect.get(target, prop, receiver)`.** Direct access breaks getters and inheritance, because `this` inside them ends up wrong. - **Expecting the `get` trap to behave with `JSON.stringify` the way a plain object does.** Serialization also goes through the traps, so computed fields can unexpectedly leak into the output. - **Reaching for a proxy where a plain getter and setter would do.** A proxy is more expensive per operation and makes debugging noticeably harder.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.