Suggest an editImprove this articleRefine the answer for “The Reflect object”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`Reflect` is a built-in object (like `Math` or `JSON`) with static methods for the basic low-level operations on objects and functions: reading, writing, deleting, checking for existence, calling and constructing.** It turns operations that used to exist only as syntax (`obj.x`, `obj.x = 1`, `delete obj.x`, `in`, `new`) into ordinary functions. The `Reflect` methods map one to one onto the `Proxy` traps, which is why you call them inside a trap to delegate the default behaviour together with the correct `receiver`. Unlike `Object`, the `Reflect` methods more often return `false` instead of throwing an exception. ```javascript const user = { name: 'Tim' }; console.log(Reflect.get(user, 'name')); // "Tim" Reflect.set(user, 'age', 30); console.log(Reflect.has(user, 'age')); // true console.log(Reflect.ownKeys(user)); // ['name', 'age'] ``` **Key point:** `Reflect` is a mirror of JavaScript's basic operations in function form, and the main partner of `Proxy`.Shown above the full answer for quick recall.Answer (EN)Image**`Reflect` is a built-in object (like `Math` or `JSON`) that holds static methods for working with objects and functions at a low level.** Put simply, it is a unified API for the basic operations on objects: reading, writing, calling, constructing and so on, and its methods correspond to the very operations you can intercept with `Proxy`. ## Theory ### TL;DR - `Reflect` is neither a class nor a function: it cannot be called with `new`, it only has static methods. - It turns the basic language operations into functions: `Reflect.get`, `Reflect.set`, `Reflect.has`, `Reflect.deleteProperty`, `Reflect.construct`. - Every `Reflect` method matches one `Proxy` trap, which is why they are called inside traps. - Unlike `Object`, the `Reflect` methods more often return `true`/`false` instead of throwing an exception. - `Reflect.ownKeys()` returns all own keys, symbols included, unlike `Object.keys()`. - The third `receiver` argument of `get`/`set` preserves the correct `this` for getters and setters that live on the prototype. ### Quick example ```javascript const user = { name: 'Tim', age: 25 }; const proxy = new Proxy(user, { get(target, prop, receiver) { console.log(`Reading property: ${prop}`); return Reflect.get(target, prop, receiver); // delegate safely }, set(target, prop, value, receiver) { console.log(`Changing property: ${prop}`); return Reflect.set(target, prop, value, receiver); } }); proxy.name; // Reading property: name proxy.age = 30; // Changing property: age ``` Using `Reflect` inside traps guarantees the behaviour stays correct even when the object has getters, setters or a prototype. ### Why it is needed Before ES6, operations such as `delete obj.prop` or `obj[prop] = value` were performed by built-in syntax but had **no functional equivalent**. `Reflect` appeared in order to: 1. make those operations available as **functions**; 2. simplify writing `Proxy` traps, because execution can be delegated through `Reflect`; 3. make the API symmetric and safe. ### The main methods by example **Reading and writing properties.** ```javascript const user = { name: 'Tim' }; console.log(Reflect.get(user, 'name')); // "Tim" Reflect.set(user, 'age', 30); console.log(user.age); // 30 ``` The plain-syntax equivalent: ```javascript user.name; // get user.age = 30; // set ``` But with `Reflect` you can use this **functionally**, passing `target`, `key` and `receiver` by hand. **Deleting a property.** ```javascript const user = { name: 'Tim' }; delete user.name; // the traditional syntax // The Reflect equivalent: Reflect.deleteProperty(user, 'name'); ``` The difference: `Reflect.deleteProperty` **returns true or false** instead of throwing an exception when the property is `configurable: false`. **Creating a property with flags.** This is the functional equivalent of `Object.defineProperty`. ```javascript const user = {}; Reflect.defineProperty(user, 'role', { value: 'admin', writable: false }); console.log(user.role); // admin ``` **Checking for a property and getting the keys.** ```javascript const user = { name: 'Tim' }; console.log('name' in user); // true console.log(Reflect.has(user, 'name')); // true const data = { a: 1, b: 2 }; console.log(Reflect.ownKeys(data)); // ['a', 'b'] ``` Unlike `Object.keys()`, `Reflect.ownKeys()` returns **all** own keys, including `Symbol` ones and non-enumerable ones. **Working with the prototype.** ```javascript const user = {}; const proto = { greet() { console.log('hi'); } }; Reflect.setPrototypeOf(user, proto); Reflect.getPrototypeOf(user).greet(); // "hi" ``` **Calling a function and constructing instances.** ```javascript function sum(a, b) { return a + b; } console.log(Reflect.apply(sum, null, [2, 3])); // 5 ``` This is the safe equivalent of `Function.prototype.apply.call(sum, ...)`, and it works even when a function has overridden `apply`. ```javascript class User { constructor(name) { this.name = name; } } const user = Reflect.construct(User, ['Tim']); console.log(user.name); // "Tim" ``` ### The full list of `Reflect` methods | Method | What it does | | --- | --- | | **Reflect.apply(target, thisArg, args)** | Calls a function with the given `this` and arguments | | **Reflect.construct(target, args)** | The equivalent of `new target(...args)` | | **Reflect.defineProperty(target, key, descriptor)** | Creates or changes a property | | **Reflect.deleteProperty(target, key)** | Deletes a property (the equivalent of `delete`) | | **Reflect.get(target, key, receiver?)** | Returns the value of a property | | **Reflect.set(target, key, value, receiver?)** | Sets the value of a property | | **Reflect.has(target, key)** | Checks whether a property exists (`in`) | | **Reflect.ownKeys(target)** | Returns all keys, `Symbol` ones included | | **Reflect.getOwnPropertyDescriptor(target, key)** | Returns a property descriptor | | **Reflect.preventExtensions(target)** | Forbids adding new properties | | **Reflect.isExtensible(target)** | Checks whether properties can be added | | **Reflect.getPrototypeOf(target)** | Gets the prototype | | **Reflect.setPrototypeOf(target, proto)** | Sets the prototype | ### How `Reflect` differs from `Object` | Aspect | `Object` | `Reflect` | | --- | --- | --- | | Orientation | Methods for working with the structure of objects | Universal low-level operations | | Error reporting | Methods may throw exceptions | Methods more often return `false` | | Functionality | Operators cannot be called as functions | They can, for example `Reflect.deleteProperty` instead of `delete` | | Relation to Proxy | None | The methods map one to one onto the Proxy traps | A summary table of the operations: | What it does | Example | | --- | --- | | Reads a property | `Reflect.get(obj, 'x')` | | Writes a property | `Reflect.set(obj, 'x', 10)` | | Checks existence | `Reflect.has(obj, 'x')` | | Deletes a property | `Reflect.deleteProperty(obj, 'x')` | | Gets the keys | `Reflect.ownKeys(obj)` | | Calls a function | `Reflect.apply(fn, thisArg, args)` | | Constructs an object | `Reflect.construct(Class, args)` | | Works with the prototype | `Reflect.getPrototypeOf(obj)` and `Reflect.setPrototypeOf(obj, proto)` | The main idea: `Reflect` is a mirror of JavaScript's basic operations in function form. It makes code cleaner, safer and more predictable, especially when working with `Proxy`. ### Common mistakes - **Trying to call `new Reflect()`.** `Reflect` is neither a function nor a constructor: it is a plain object with static methods, like `Math`. - **Ignoring the result of `Reflect.set` or `Reflect.defineProperty`.** They return `false` instead of throwing, so a silent write failure easily goes unnoticed. - **Forgetting to pass `receiver` in a `get`/`set` trap.** Without it a prototype getter receives `target` instead of the proxy, and reactivity or logging misses part of the accesses. - **Confusing `Reflect.ownKeys()` with `Object.keys()`.** The former also returns symbols and non-enumerable properties, so the result is wider than expected. - **Assuming `Reflect.get(obj, 'x')` always equals `obj.x`.** If you pass a different `receiver` as the third argument, the getter runs with a different `this`. - **Using `Reflect` where plain syntax is enough.** Outside `Proxy` traps and metaprogramming, `obj.x` reads better than `Reflect.get(obj, 'x')`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.