Що робить об'єкт Proxy?
Proxy - це один із найпотужніших і "магічних" інструментів у JavaScript.
Він дозволяє перехоплювати і перевизначати поведінку об'єктів -
тобто ставати "між" об'єктом і його використанням.
Що таке Proxy:
Proxy - це обгортка навколо об'єкта,
яка дозволяє перехоплювати операції з ним: читання, запис, видалення властивостей, виклики функцій і т.д.
Можна "перевизначити" поведінку об'єкта - як він реагує на obj.prop, obj[key], delete obj.x, in obj і багато іншого.
Синтаксис:
const proxy = new Proxy(target, handler);| Аргумент | Опис |
|---|---|
target | оригінальний об'єкт, який обгортаємо |
handler | об'єкт з "пастками" (функціями-перехоплювачами) |
Найпростіший приклад:
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) | виклик через new | new proxy() |
Приклад: логування змін
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Тепер ти можеш "ловити" всі зміни в об'єкті.
Приклад: захист від видалення властивостей
const obj = { secret: 42 };
const proxy = new Proxy(obj, {
deleteProperty(target, prop) {
console.log(`Видалення заборонено: ${prop}`);
return false;
}
});
delete proxy.secret; // "Видалення заборонено: secret"Приклад: валідація даних
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Можна навісити "правила" на запис властивостей - чудова техніка для валідації даних.
Приклад: значення за замовчуванням
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)
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 та ін.)
Приклад: перехоплення виклику функції
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 |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.