Що робить Reflect?
Що таке Reflect
Reflect - це вбудований об'єкт (як Math або JSON), який містить статичні методи для роботи з об'єктами і функціями на низькому рівні.
Простіше кажучи:
Reflect- це "уніфікований API" для базових операцій над об'єктами: читання, запис, виклик, створення тощо. Його методи відповідають тим самим операціям, які можна перехоплювати черезProxy.
Навіщо він потрібен
Раніше (до ES6) операції на кшталт delete obj.prop або obj[prop] = value виконувалися "вбудованим синтаксисом", але не мали функціонального аналога.
Reflect з'явився, щоб:
- Зробити ці операції доступними як функції;
- Спростити написання пасток
Proxy(можна делегувати виконання черезReflect); - Зробити API симетричним і безпечним.
Приклад 1 - безпечне читання і запис властивостей
const user = { name: "Tim" };
console.log(Reflect.get(user, "name")); // "Tim"
Reflect.set(user, "age", 30);
console.log(user.age); // 30Аналог:
user.name; // get
user.age = 30; // setАле з Reflect ти можеш використовувати це функціонально, передаючи target, key, receiver вручну.
Приклад 2 - видалення властивості
const user = { name: "Tim" };
delete user.name; // традиційний синтаксис
// Еквівалент через Reflect:
Reflect.deleteProperty(user, "name");Відмінність: Reflect.deleteProperty повертає true/false, а не кидає виняток, якщо властивість "configurable: false".
Приклад 3 - створення властивості з флагами
const user = {};
Reflect.defineProperty(user, "role", {
value: "admin",
writable: false
});
console.log(user.role); // admin(це функціональний аналог Object.defineProperty)
Приклад 4 - перевірка наявності властивості
const user = { name: "Tim" };
console.log("name" in user); // true
console.log(Reflect.has(user, "name")); // trueПриклад 5 - отримання ключів
const user = { a: 1, b: 2 };
console.log(Reflect.ownKeys(user)); // ['a', 'b']На відміну від Object.keys(), повертає всі ключі, включно з Symbol.
Приклад 6 - керування прототипом
const user = {};
const proto = { greet() { console.log("hi"); } };
Reflect.setPrototypeOf(user, proto);
Reflect.getPrototypeOf(user).greet(); // "hi"Приклад 7 - виклик функції
function sum(a, b) {
return a + b;
}
console.log(Reflect.apply(sum, null, [2, 3])); // 5Це безпечний аналог Function.prototype.apply.call(sum, ...)
Приклад 8 - створення екземплярів
class User {
constructor(name) {
this.name = name;
}
}
const user = Reflect.construct(User, ["Tim"]);
console.log(user.name); // "Tim"Список усіх методів Reflect
| Метод | Що робить |
|---|---|
| Reflect.apply(target, thisArg, args) | Викликає функцію з указаним this і аргументами |
| Reflect.construct(target, args) | Аналог new target(...args) |
| Reflect.defineProperty(target, key, descriptor) | Створює/змінює властивість |
| Reflect.deleteProperty(target, key) | Видаляє властивість (аналог delete) |
| Reflect.get(target, key, receiver?) | Повертає значення властивості |
| Reflect.set(target, key, value, receiver?) | Встановлює значення властивості |
| Reflect.has(target, key) | Перевіряє наявність властивості (in) |
| Reflect.ownKeys(target) | Повертає всі ключі (включно з Symbol) |
| Reflect.getOwnPropertyDescriptor(target, key) | Повертає дескриптор властивості |
| Reflect.preventExtensions(target) | Забороняє додавати нові властивості |
| Reflect.isExtensible(target) | Перевіряє, чи можна додавати властивості |
| Reflect.getPrototypeOf(target) | Отримує прототип |
| Reflect.setPrototypeOf(target, proto) | Встановлює прототип |
Приклад 9 - Reflect + Proxy (класична зв'язка)
const user = { name: "Tim", age: 25 };
const proxy = new Proxy(user, {
get(target, prop, receiver) {
console.log(`Читання властивості: ${prop}`);
return Reflect.get(target, prop, receiver); // безпечно делегуємо
},
set(target, prop, value, receiver) {
console.log(`Зміна властивості: ${prop}`);
return Reflect.set(target, prop, value, receiver);
}
});
proxy.name; // Читання властивості: name
proxy.age = 30; // Зміна властивості: ageВикористання Reflect всередині пасток гарантує, що поведінка буде коректною, навіть якщо об'єкт має геттери, сеттери або прототип.
Відмінність Reflect від Object
| Особливість | Object | Reflect |
|---|---|---|
| Орієнтація | Методи для роботи зі структурою об'єктів | Універсальні низькорівневі операції |
| Повернення помилок | Методи можуть кидати винятки | Методи частіше повертають false |
| Функціональність | Не можна викликати оператори як функції | Можна (наприклад, Reflect.deleteProperty замість delete) |
| Зв'язок з Proxy | Немає | Методи 1-в-1 відповідають пасткам Proxy |
Підсумок
| Що робить | Приклад |
|---|---|
| Читає властивість | Reflect.get(obj, "x") |
| Пише властивість | Reflect.set(obj, "x", 10) |
| Перевіряє наявність | Reflect.has(obj, "x") |
| Видаляє властивість | Reflect.deleteProperty(obj, "x") |
| Отримує ключі | Reflect.ownKeys(obj) |
| Викликає функцію | Reflect.apply(fn, thisArg, args) |
| Створює об'єкт | Reflect.construct(Class, args) |
| Працює з прототипом | Reflect.getPrototypeOf(obj) / Reflect.setPrototypeOf(obj, proto) |
Головна ідея:
Reflect- це "дзеркало" базових операцій JavaScript у вигляді функцій. Він робить код чистішим, безпечнішим і передбачуванішим, особливо під час роботи зProxy.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.