Коротка відповідь
juniorProxy — це об’єкт, що перехоплює операції над цільовим об’єктом. Він дозволяє змінювати поведінку доступу, валідації або логування без зміни коду цільового об’єкта. Наприклад, `const p = new Proxy(target, { get: (t,k)=>{ console.log(k); return t[k]; } });`
Повне пояснення
Що це і навіщо Proxy – об’єкт‑обгортка, що перехоплює операції (get, set, apply, construct тощо) над цільовим об’єктом. Це корисно для валідації, логування, кешування, спостереження за змінами або створення «виробних» об’єктів без прямого доступу до внутрішньої логіки.
Ключові принципи/терміни
- handler – об’єкт, що містить ловці (traps).
- target – оригінальний об’єкт, над яким виконується перехоплення.
- trap – функція‑ловець, що відповідає за конкретну операцію.
- revocable – можливість «відключити» проксі за допомогою
Proxy.revocable.
Як це працює При виклику операції над проксі JavaScript шукає відповідний trap у handler‑і. Якщо trap існує, виконується його код; інакше – операція проксуюється до target‑у. Це дозволяє модифікувати або перезаписувати результат.
Практика і реалізація (JS/TS)
const target = { a: 1 };
const handler = {
get(t, prop) {
console.log(`Accessing ${String(prop)}`);
return t[prop];
},
set(t, prop, value) {
if (prop === 'a' && typeof value !== 'number') throw new TypeError('a must be number');
t[prop] = value;
return true;
}
};
const proxy = new Proxy(target, handler);
proxy.a; // logs "Accessing a"
proxy.b = 2;
Тестування
import { describe, it } from 'vitest';
describe('Proxy get trap', () => {
it('logs property access', () => {
const log = [];
const p = new Proxy({x: 10}, { get(t, k){ log.push(k); return t[k]; } });
p.x;
expect(log).toEqual(['x']);
});
});
Безпека і приватність
Проксі можна використовувати для приховування внутрішніх полів: створюючи trap get з перевіркою, що лише дозволені ключі повертаються. Також можна обмежити доступ до методів, що містять чутливі дані.
Особливості в контексті JS Core
- Підтримка
Proxyє частиною ECMAScript 2015. - Працює з будь‑яким типом об’єкта (об’єкт, функція, масив).
- Підтримка
revocableдозволяє «заблокувати» проксі після використання.
Оптимізація, типові помилки та edge cases
- Перевантаження trap‑ів (наприклад,
getіset) може впливати на продуктивність. - Необхідно обробляти
Symbol‑ключі, якщо вони використовуються. - Якщо trap повертає
undefined, це може призвести до непередбачуваних результатів.
Диагностика і відладка
| Симптом | Причина | Діяльність |
|---|---|---|
| Невірний результат при доступі | Trap не виконується | Переконатися, що trap оголошено в handler‑і |
Виникає TypeError при встановленні | Перевірка типу не відповідає | Змінити логіку в set |
Альтернативи
- Власні гетери/сетери в класах.
- Декоратори (наприклад,
@logу TypeScript).