Перейти к содержимому

Proxy & Reflect

В одной фразе: Proxy перехватывает фундаментальные операции объекта через ловушки (get, set, has, deleteProperty и др.); Reflect — зеркальный API для тех же операций, нужный для корректного forwarding с сохранением receiver и инвариантов. На собесе важно объяснить зачем именно нужен Reflect, а не просто target[prop].

// Validation proxy: проверяем данные на уровне объекта
function createValidated(schema) {
return new Proxy({}, {
set(target, prop, value, receiver) {
if (prop in schema && !schema[prop](value)) {
throw new TypeError(`Invalid ${prop}: ${value}`);
}
// Reflect.set: учитывает receiver, возвращает boolean
return Reflect.set(target, prop, value, receiver);
// не просто target[prop] = value — Reflect правильнее
},
get(target, prop, receiver) {
return Reflect.get(target, prop, receiver);
}
});
}
const user = createValidated({ age: v => Number.isInteger(v) && v >= 0 });
user.age = 25; // OK
// user.age = -1; // TypeError: Invalid age: -1
// Reflect: возвращает boolean вместо броска, единый API
const target = { x: 1 };
// Object.defineProperty бросает TypeError при неудаче
// Reflect.defineProperty возвращает false — удобнее в условиях
const ok = Reflect.defineProperty(target, 'y', { value: 2, writable: false });
console.log(ok); // true
// Reflect.ownKeys — все ключи: string + symbol + non-enumerable
const sym = Symbol('s');
const obj = { a: 1, [sym]: 2 };
Object.defineProperty(obj, 'b', { value: 3, enumerable: false });
Reflect.ownKeys(obj); // ['a', 'b', Symbol(s)]
// Proxy непрозрачен для ===
const target = {};
const proxy = new Proxy(target, {});
proxy === target; // false — разные объекты!
// Ловушки имеют инварианты: нельзя нарушить non-configurable свойства
const obj2 = Object.defineProperty({}, 'x', { value: 1, configurable: false, writable: false });
const p = new Proxy(obj2, {
get() { return 99; } // ← попытка нарушить инвариант
});
// p.x → TypeError: proxy must report the same value
// (движок защищает non-configurable non-writable свойства)

Итог: Proxy + Reflect — основа реактивных систем (Vue 3), валидации и логирования. Reflect обеспечивает корректный forward с сохранением receiver и инвариантов.