Skip to main content

Що робить Reflect?

Що таке Reflect

Reflect - це вбудований об'єкт (як Math або JSON), який містить статичні методи для роботи з об'єктами і функціями на низькому рівні.

Простіше кажучи:

Reflect - це "уніфікований API" для базових операцій над об'єктами: читання, запис, виклик, створення тощо. Його методи відповідають тим самим операціям, які можна перехоплювати через Proxy.

Навіщо він потрібен

Раніше (до ES6) операції на кшталт delete obj.prop або obj[prop] = value виконувалися "вбудованим синтаксисом", але не мали функціонального аналога. Reflect з'явився, щоб:

  1. Зробити ці операції доступними як функції;
  2. Спростити написання пасток Proxy (можна делегувати виконання через Reflect);
  3. Зробити API симетричним і безпечним.

Приклад 1 - безпечне читання і запис властивостей

javascript
const user = { name: "Tim" }; console.log(Reflect.get(user, "name")); // "Tim" Reflect.set(user, "age", 30); console.log(user.age); // 30

Аналог:

javascript
user.name; // get user.age = 30; // set

Але з Reflect ти можеш використовувати це функціонально, передаючи target, key, receiver вручну.

Приклад 2 - видалення властивості

javascript
const user = { name: "Tim" }; delete user.name; // традиційний синтаксис // Еквівалент через Reflect: Reflect.deleteProperty(user, "name");

Відмінність: Reflect.deleteProperty повертає true/false, а не кидає виняток, якщо властивість "configurable: false".

Приклад 3 - створення властивості з флагами

javascript
const user = {}; Reflect.defineProperty(user, "role", { value: "admin", writable: false }); console.log(user.role); // admin

(це функціональний аналог Object.defineProperty)

Приклад 4 - перевірка наявності властивості

javascript
const user = { name: "Tim" }; console.log("name" in user); // true console.log(Reflect.has(user, "name")); // true

Приклад 5 - отримання ключів

javascript
const user = { a: 1, b: 2 }; console.log(Reflect.ownKeys(user)); // ['a', 'b']

На відміну від Object.keys(), повертає всі ключі, включно з Symbol.

Приклад 6 - керування прототипом

javascript
const user = {}; const proto = { greet() { console.log("hi"); } }; Reflect.setPrototypeOf(user, proto); Reflect.getPrototypeOf(user).greet(); // "hi"

Приклад 7 - виклик функції

javascript
function sum(a, b) { return a + b; } console.log(Reflect.apply(sum, null, [2, 3])); // 5

Це безпечний аналог Function.prototype.apply.call(sum, ...)

Приклад 8 - створення екземплярів

javascript
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 (класична зв'язка)

javascript
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

ОсобливістьObjectReflect
ОрієнтаціяМетоди для роботи зі структурою об'єктівУніверсальні низькорівневі операції
Повернення помилокМетоди можуть кидати виняткиМетоди частіше повертають 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.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.