What does Reflect.defineProperty() do?
Reflect.defineProperty() is a modern counterpart to Object.defineProperty(),
but with more predictable and safe behavior.
It defines (adds or changes) an object property with a given descriptor (property descriptor) and returns a boolean value indicating whether the operation succeeded.
In short
Syntax:
Reflect.defineProperty(target, propertyKey, descriptor)| Argument | Description |
|---|---|
target | The object in which to define the property |
propertyKey | The property name (a string or Symbol) |
descriptor | The descriptor - an object with flags (value, writable, enumerable, configurable, get, set) |
Returns:
true- if the property was successfully defined,false- if the operation failed (for example, the object is protected).
Example - regular usage
const user = {};
const result = Reflect.defineProperty(user, 'name', {
value: 'Alex',
writable: true,
enumerable: true,
configurable: true
});
console.log(result); // true
console.log(user.name); // "Alex"The same as:
Object.defineProperty(user, 'name', { ... })but with an important difference: Reflect does not throw an exception, it just returns false.
Difference from Object.defineProperty()
| Behavior | Object.defineProperty() | Reflect.defineProperty() |
|---|---|---|
| Returns | the object itself | true / false |
| On error | throws an exception | returns false |
| Suited for | regular code | safe, "reflective" operations |
"Reflective" means working with an object's internal properties without throwing exceptions.
Example: safe check
const frozen = Object.freeze({});
try {
Object.defineProperty(frozen, 'x', { value: 1 });
} catch (e) {
console.log('Error:', e.message);
}
console.log(Reflect.defineProperty(frozen, 'x', { value: 1 })); // false (no error)Reflect.defineProperty() simply returns false,
instead of throwing an exception.
Example with accessors
const person = {};
Reflect.defineProperty(person, 'fullName', {
get() {
return 'Alex Johnson';
},
enumerable: true
});
console.log(person.fullName); // "Alex Johnson"Works the same way for data and accessor descriptors.
Example: dynamic property definition
const obj = {};
['name', 'age', 'city'].forEach(key => {
Reflect.defineProperty(obj, key, {
value: key.toUpperCase(),
enumerable: true
});
});
console.log(obj);
// { name: 'NAME', age: 'AGE', city: 'CITY' }The return value is useful in conditional operations
if (Reflect.defineProperty(user, 'role', { value: 'admin' })) {
console.log('Property successfully added');
} else {
console.log('Failed to add property');
}Convenient because it does not require try/catch.
Example of interaction with Proxy
In the defineProperty trap of a Proxy, the Reflect.defineProperty method
is used to delegate the default behavior:
const target = {};
const proxy = new Proxy(target, {
defineProperty(target, key, descriptor) {
console.log(`Adding property "${key}"`);
return Reflect.defineProperty(target, key, descriptor);
}
});
proxy.x = 10; // automatically calls Reflect.defineProperty under the hoodIn Proxy, reflective methods (Reflect.*) help
implement behavior as "naturally" as possible.
SUMMARY
| What it does | Defines (creates/changes) an object property with the given descriptor |
|---|---|
| Returns | true on success, false on failure |
| Does not throw errors | Yes |
| Uses a descriptor | Yes (value, writable, configurable, enumerable, get, set) |
| Used in | Safe operations, Proxy, metaprogramming |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.