proxy 默认不代理嵌套对象,需在 get 中按需递归代理并用 weakmap 缓存;reflect.get 确保安全读取;set 中仅触发通知,新对象需递归代理并缓存。

Proxy 本身不自动处理嵌套对象,它只拦截目标对象自身属性的读写操作。要让 obj.a.b.c 这类深层路径也能被监听,关键在于在 get 拦截器中做“按需代理”——即每次取值时,对返回的对象再套一层 Proxy。
核心机制:get 中惰性递归代理
访问 proxy.user.profile.name 时:
-
proxy.user触发一次get,返回原始user对象(还不是 Proxy) - 接着访问
user.profile,此时已脱离 Proxy 范围,无法拦截 - 正确做法是在
get返回前判断:若值是普通对象且未被代理过,就立即用同一套逻辑创建新 Proxy 并缓存
必须用 WeakMap 缓存代理实例
否则每次访问都会新建 Proxy,导致内存暴涨、无限递归甚至页面卡死:
macOS 微信消息自动化工具。通过 GUI 自动化实现:发送消息给指定联系人、读取聊天内容、监控新消息。适用于需要自动化微信操作的场景,如定时发送、批量回复、消息备份等。依赖 peekaboo 进行屏幕截图和 UI 交互。仅支持 macOS。开源地址:https://github.com/chairmanmia...
- 声明
const proxyCache = new WeakMap() - 在
get中先查缓存:if (proxyCache.has(value)) return proxyCache.get(value) - 仅当
value是 plain object 且未缓存时,才调用createReactive(value)并存入缓存 - 跳过 Date、RegExp、Map、Set 等原生类型,它们通常不该响应式化
Reflect.get 是安全读取的必要保障
不能直接写 target[key],否则会出问题:
- 绕过原型链上的 getter,丢失
this绑定(比如 class 实例里的 accessor) - 无法正确处理 Symbol 属性和计算属性名
-
Reflect.get(target, key, receiver)才是语义等价的标准行为,receiver 确保代理对象作为this传入 getter
set 拦截只需触发通知,不解耦 DOM
set 的职责很明确:
- 先用
Reflect.set()完成真实赋值 - 再调用
trigger(key, oldValue, newValue)通知依赖更新 - 不要在 handler 里写具体 DOM 操作(如
el.innerText = newValue),那是上层 effect 的事 - 如果新值是对象,也要递归代理并缓存,否则后续修改不会被监听










