Proxy实现响应式需拦截读写并配合依赖管理:通过get/set收集和触发依赖,递归代理深层对象,用WeakMap存储依赖关系,并补充ownKeys、deleteProperty、has等拦截器支持数组和特殊操作。

用 Proxy 实现对象的响应式触发,关键在于拦截读写操作并配合依赖管理机制——不是只做“监听”,而是让读写行为能自动关联更新逻辑。
Proxy 代理对象的基本结构
必须用 new Proxy(target, handler) 包裹原始对象,handler 中至少定义 get 和 set 拦截器:
-
get在取值时触发,用于记录“谁正在读这个属性”(即依赖收集) -
set在赋值时触发,用于通知“所有依赖这个属性的地方该更新了”(即触发更新) - 务必返回
Reflect.get()和Reflect.set(),保证原语义不被破坏
支持嵌套对象的递归代理
Proxy 默认只代理第一层,深层属性(如 obj.user.name)不会自动响应。解决办法是在 get 中判断返回值是否为对象,并递归调用 reactive:
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
- 读取属性时,先用
Reflect.get(target, key)获取值 - 若值是对象且非 null,且尚未被代理过,就对它再调一次
reactive() - 这样每次访问深层属性,都会自动创建对应层级的代理,实现深度响应
依赖收集与触发的核心配合
Proxy 本身不保存依赖,需要外部维护一个映射表(如 WeakMap<target, Map<key, Set<effect>>>):
-
track(target, key)在get中调用,把当前正在执行的副作用函数(如组件 render)存入该属性的依赖集合 -
trigger(target, key)在set中调用,遍历该属性对应的依赖集合,逐一执行其中的函数 - 确保
activeEffect全局变量在 effect 执行前正确设置,才能让 track 知道“当前是谁在读”
处理数组和特殊操作
数组索引赋值、push、length 修改等操作,仅靠 set 拦截不够,需补充其他拦截器:
- 用
ownKeys拦截for...in、Object.keys()等遍历操作 - 用
deleteProperty拦截delete obj.key,并触发对应依赖 - 用
has拦截in操作符,确保key in obj也能被追踪 - 对数组,
set已能捕获arr[0] = x和arr.length = n,无需重写原型方法

















