Proxy и Reflect
↑ 2.1 JavaScript: продвинутый · ← Предыдущая · → Следующая
Зачем это на собесе
Proxy — основа реактивности Vue 3. Вопрос «как работает реактивность» требует понимания перехватчиков.
Объяснение
Proxy оборачивает объект и перехватывает операции через ловушки (traps); Reflect предоставляет методы стандартного поведения тех же операций.
function reactive(target, onChange) {
return new Proxy(target, {
get(obj, key, receiver) {
track(obj, key); // зависимость (как во Vue)
const v = Reflect.get(obj, key, receiver);
return typeof v === "object" && v !== null ? reactive(v, onChange) : v; // вложенная реактивность
},
set(obj, key, value, receiver) {
const ok = Reflect.set(obj, key, value, receiver);
onChange(key, value);
return ok; // в строгом режиме нужно вернуть true
},
has(obj, key) { return key in obj && !key.startsWith("_"); },
deleteProperty(obj, key) { onChange(key); return Reflect.deleteProperty(obj, key); },
});
}| Ловушка | Перехватывает |
|---|---|
get, set, has, deleteProperty | чтение, запись, in, delete |
ownKeys, getOwnPropertyDescriptor | перечисление ключей |
apply, construct | вызов функции, new |
getPrototypeOf | прототип |
Применения: реактивность (Vue 3 reactive), валидация, логирование, значения по умолчанию, ленивые объекты, API-обёртки (api.users.get(1) → HTTP).
Reflect нужен, чтобы корректно пробросить receiver и this, вернуть булевый результат вместо исключения.
Vue 2 использовал Object.defineProperty (не видел добавление/удаление свойств и индексы массива), Vue 3 — Proxy (видит всё, но не поддерживается в IE).
Нюансы и подводные камни
- Прокси не равен исходному объекту (
proxy !== target): идентичность нарушается (проблема при сравнении,Map-ключах). - Встроенные объекты с внутренними слотами (
Map,Date) требуют привязки методов (this— прокси). - Накладные расходы на каждую операцию: не оборачивайте горячие пути.
- Отмена доступа:
Proxy.revocable. - Во Vue деструктуризация реактивного объекта теряет реактивность (
toRefs).
Практика
- Реализуйте мини-
reactiveсtrack/trigger. - Сделайте прокси для валидации присвоения типов.
- Обёртка API-клиента через
Proxy.
Вопросы с ответами
Как Vue 3 реализует реактивность?
Через
Proxy:getотслеживает зависимости эффектов,setуведомляет подписчиков.
Зачем Reflect в ловушках?
Для корректного стандартного поведения и проброса
receiver.