Skip to main content

Чим Reflect відрізняється від Object?

Reflect і Object дійсно схожі (обидва працюють із властивостями об'єктів), але вони створені для різних цілей. Різниця між ними - у філософії, поведінці та застосуванні.

Розберемо по кроках:


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

КритерійObjectReflect
Основне призначенняРобота з об'єктами (створення, прототипи, властивості)Метапрограмування - "керування поведінкою" об'єктів
ВиникЗ самого початку JSУ ES6 (ES2015)
Поведінка при помилкахКидає виняткиПовертає true / false
Використовується взвичайному кодіProxy, безпечних викликах, внутрішніх операціях
Тип результатуРізний (об'єкт, значення тощо)Майже завжди булеве значення або примітив
Статус"старе" API"сучасне, відображальне" API

Приклад - defineProperty

Object:

javascript
try { Object.defineProperty({}, 'x', { value: 1, writable: false }); console.log('ok'); } catch { console.log('Помилка!'); }

Якщо операція не вдалася (наприклад, об'єкт заморожений) - буде кинуто помилку.


Reflect:

javascript
const obj = Object.freeze({}); const result = Reflect.defineProperty(obj, 'x', { value: 1 }); console.log(result); // false (без помилки)

Reflect.defineProperty() просто поверне false, а не перерве виконання програми.


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

Через delete

javascript
const user = { name: 'Tim' }; delete user.name; // true

Через Reflect (безпечніше)

javascript
const user = { name: 'Tim' }; console.log(Reflect.deleteProperty(user, 'name')); // true console.log(Reflect.deleteProperty(Object.freeze({x: 4}), 'x')); // false

Reflect.deleteProperty() робить те саме, але не кидає помилок і повертає логічний результат.


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

javascript
function greet(msg) { console.log(msg, this.name); } const user = { name: 'Tim' }; Reflect.apply(greet, user, ['Привіт']); // "Привіт Tim"

Reflect.apply() - аналог Function.prototype.apply(), але більш явний і зручний для Proxy-пасток і метапрограмування.


Приклад - створення об'єкта

javascript
class User { constructor(name) { this.name = name; } } const tim = Reflect.construct(User, ['Tim']); console.log(tim.name); // "Tim"

Reflect.construct() - "відображальна" версія new, корисна, якщо потрібно динамічно створити екземпляр класу.


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

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

Reflect.has() - це те саме, що оператор in, але як функція (зручно при динамічних викликах).


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

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

Аналог user.name = ... та user.name, але у "функціональній" формі (зручно використовувати в Proxy).


Поведінка при помилках

МетодObjectReflect
Object.defineProperty(frozen, 'x', {...})кидає помилкуповертає false
Object.getPrototypeOf(null)TypeErrorповертає false
Object.setPrototypeOf(sealed, ...)кидає помилкуповертає false

Тобто Reflect - "тихий" і передбачуваний варіант Object-методів.


Методи, яких немає в Object

Метод ReflectЩо робитьАналог
Reflect.apply()Викликає функцію із зазначеним this і аргументамиfunc.apply()
Reflect.construct()Аналог оператора new-
Reflect.get() / Reflect.set()Отримує / задає значення властивостіobj[key]
Reflect.has()Перевіряє наявність властивості'key' in obj
Reflect.deleteProperty()Видаляє властивістьdelete obj.key
Reflect.ownKeys()Повертає всі ключі (включно з Symbol)Object.getOwnPropertyNames() + Object.getOwnPropertySymbols()

Приклад реального застосування - Proxy

Reflect ідеально працює в парі з Proxy, щоб типово пробрасувати стандартну поведінку.

javascript
const user = { name: 'Tim' }; const proxy = new Proxy(user, { get(target, key) { console.log(`Читання ${key}`); return Reflect.get(target, key); // безпечно делегуємо } }); console.log(proxy.name); // Вивід: // Читання name // "Tim"

Без Reflect.get() довелося б вручну писати target[key], а це може спричинити помилки у складніших випадках (аксесори, прототипи тощо).


Підсумок

КритерійObjectReflect
МетаРобота з властивостями і прототипамиМетапрограмування, "відображення" поведінки
ВиникЗ самого початку JSES6 (2015)
При помилціКидає винятокПовертає false
Значення, що повертаєтьсяРізнеПередбачуване
Підтримка ProxyНемаєТак
Зручність у функціональних викликахСередняВисока

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

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

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