Skip to main content

Що робить об'єкт Proxy?

Proxy - це один із найпотужніших і "магічних" інструментів у JavaScript. Він дозволяє перехоплювати і перевизначати поведінку об'єктів - тобто ставати "між" об'єктом і його використанням.


Що таке Proxy:

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

Можна "перевизначити" поведінку об'єкта - як він реагує на obj.prop, obj[key], delete obj.x, in obj і багато іншого.


Синтаксис:

javascript
const proxy = new Proxy(target, handler);
АргументОпис
targetоригінальний об'єкт, який обгортаємо
handlerоб'єкт з "пастками" (функціями-перехоплювачами)

Найпростіший приклад:

javascript
const user = { name: "Alice", age: 25 }; const proxy = new Proxy(user, { get(target, prop) { console.log(`Доступ до властивості "${prop}"`); return target[prop]; } }); console.log(proxy.name); // Доступ до властивості "name" -> Alice

Кожного разу, коли відбувається proxy.name, виклик іде через пастку get(), а не напряму в об'єкт.


Основні "пастки" (traps):

ПасткаПерехоплюєПриклад
get(target, prop)читання властивостіproxy.x
set(target, prop, value)запис властивостіproxy.x = 10
has(target, prop)оператор in"x" in proxy
deleteProperty(target, prop)delete proxy.x
ownKeys(target)Object.keys(proxy)
apply(target, thisArg, args)виклик функціїproxy()
construct(target, args)виклик через newnew proxy()

Приклад: логування змін

javascript
const user = { name: "Alice" }; const proxy = new Proxy(user, { set(target, prop, value) { console.log(`Змінено ${prop}: ${target[prop]} -> ${value}`); target[prop] = value; return true; // обов'язково повернути true } }); proxy.name = "Bob"; // Змінено name: Alice -> Bob

Тепер ти можеш "ловити" всі зміни в об'єкті.


Приклад: захист від видалення властивостей

javascript
const obj = { secret: 42 }; const proxy = new Proxy(obj, { deleteProperty(target, prop) { console.log(`Видалення заборонено: ${prop}`); return false; } }); delete proxy.secret; // "Видалення заборонено: secret"

Приклад: валідація даних

javascript
const user = {}; const proxy = new Proxy(user, { set(target, prop, value) { if (prop === "age" && typeof value !== "number") { throw new TypeError("Вік має бути числом"); } target[prop] = value; return true; } }); proxy.age = 30; // OK proxy.age = "thirty"; // TypeError

Можна навісити "правила" на запис властивостей - чудова техніка для валідації даних.


Приклад: значення за замовчуванням

javascript
const data = { a: 1 }; const proxy = new Proxy(data, { get(target, prop) { return prop in target ? target[prop] : "Немає даних"; } }); console.log(proxy.a); // 1 console.log(proxy.b); // "Немає даних"

Тепер доступ до неіснуючої властивості не видає undefined, а повертає гарне значення за замовчуванням.


Приклад: спостерігач (reactive data, як у Vue.js)

javascript
function reactive(obj) { return new Proxy(obj, { set(target, prop, value) { console.log(`Оновлено ${prop}: ${value}`); target[prop] = value; return true; } }); } const state = reactive({ count: 0 }); state.count++; // "Оновлено count: 1"

Саме так реалізовані реактивні дані у фреймворках (Vue, MobX та ін.)


Приклад: перехоплення виклику функції

javascript
function sum(a, b) { return a + b; } const proxy = new Proxy(sum, { apply(target, thisArg, args) { console.log(`Виклик з аргументами: ${args}`); return target(...args) * 2; // змінюємо результат! } }); console.log(proxy(2, 3)); // Виклик з аргументами: 2,3 -> 10

Можна обгортати навіть функції, змінюючи їхню поведінку "на льоту".


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

Логування та відлагодження Валідація даних Реактивні об'єкти (наприклад, Vue.js) Lazy-loading (лінива ініціалізація) Безпечні "readonly" структури Створення API з "магічними" властивостями


Коротко:

ВластивістьProxy
Що робитьПерехоплює операції з об'єктом
Працює зОб'єктами і функціями
Використовується длялогування, валідації, реактивності
Змінює оригінал?Ні, обгортає його
Приклади пастокget, set, apply, deleteProperty, construct

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

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

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