Що робить Reflect.defineProperty()?
Reflect.defineProperty() - це сучасний аналог Object.defineProperty(),
але з більш передбачуваною та безпечною поведінкою.
Він визначає (додає або змінює) властивість об'єкта із заданим дескриптором (property descriptor) і повертає булеве значення, що вказує, чи вдалося це зробити.
Коротко
Синтаксис:
Reflect.defineProperty(target, propertyKey, descriptor)| Аргумент | Опис |
|---|---|
target | Об'єкт, у якому потрібно визначити властивість |
propertyKey | Ім'я властивості (рядок або Symbol) |
descriptor | Дескриптор - об'єкт з флагами (value, writable, enumerable, configurable, get, set) |
Повертає:
true- якщо властивість успішно визначено,false- якщо операція не вдалася (наприклад, об'єкт захищений).
Приклад - звичайне використання
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"Те саме, що:
Object.defineProperty(user, 'name', { ... })але з важливою відмінністю - Reflect не викидає виняток, а просто повертає false.
Відмінність від Object.defineProperty()
| Поведінка | Object.defineProperty() | Reflect.defineProperty() |
|---|---|---|
| Повертає | сам об'єкт | true / false |
| При помилці | викидає виняток | повертає false |
| Підходить для | звичайного коду | безпечних, "рефлективних" операцій |
"Рефлективний" - означає такий, що працює з внутрішніми властивостями об'єктів без викидання винятків.
Приклад: безпечна перевірка
const frozen = Object.freeze({});
try {
Object.defineProperty(frozen, 'x', { value: 1 });
} catch (e) {
console.log('Помилка:', e.message);
}
console.log(Reflect.defineProperty(frozen, 'x', { value: 1 })); // false (без помилки)Reflect.defineProperty() просто поверне false,
замість того щоб викидати виняток.
Приклад з аксесорами
const person = {};
Reflect.defineProperty(person, 'fullName', {
get() {
return 'Alex Johnson';
},
enumerable: true
});
console.log(person.fullName); // "Alex Johnson"Працює однаково для data та accessor дескрипторів.
Приклад: динамічне визначення властивостей
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' }Повернене значення корисне в умовних операціях
if (Reflect.defineProperty(user, 'role', { value: 'admin' })) {
console.log('Властивість успішно додано');
} else {
console.log('Не вдалося додати властивість');
}Зручно, тому що не потребує try/catch.
Приклад взаємодії з Proxy
У пастці defineProperty в Proxy метод Reflect.defineProperty
використовується, щоб делегувати поведінку за замовчуванням:
const target = {};
const proxy = new Proxy(target, {
defineProperty(target, key, descriptor) {
console.log(`Додаємо властивість "${key}"`);
return Reflect.defineProperty(target, key, descriptor);
}
});
proxy.x = 10; // автоматично викликає Reflect.defineProperty під капотомУ Proxy рефлективні методи (Reflect.*) допомагають
реалізувати поведінку максимально "природно".
ПІДСУМОК
| Що робить | Визначає (створює/змінює) властивість об'єкта із зазначеним дескриптором |
|---|---|
| Повертає | true при успіху, false при невдачі |
| Не викидає помилок | Так |
| Використовує дескриптор | Так (value, writable, configurable, enumerable, get, set) |
| Застосовується в | Безпечних операціях, Proxy, метапрограмуванні |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.