深层嵌套对象的懒加载代理需在首次访问属性时动态创建proxy,用weakmap缓存避免重复代理和内存泄漏,并通过类型判断、循环引用检测及深度/字段白名单控制代理范围。

Proxy 本身不自动递归代理嵌套对象,要实现深层嵌套对象的懒加载代理,核心思路是:**只在首次访问某个属性时,才为该属性对应的值创建 Proxy,而非初始化时就递归包装全部子对象**。
延迟代理子对象(Lazy Proxy)
对每个属性的 getter 进行拦截,检查其值是否为对象。若为对象且尚未被代理,则动态创建并缓存一个新的 Proxy;否则直接返回已缓存的代理或原始值。
- 用 WeakMap 缓存已代理的对象,避免内存泄漏(键为原始对象,值为对应 Proxy)
- 在 get 拦截器中判断 target[prop] 是否为 object 且非 null,再决定是否 wrap
- 避免对 Date、RegExp、Array 等内置类型误代理(可加 instanceof 或 toStringTag 判断)
避免重复代理与循环引用
同一原始对象多次被访问时,应复用已有 Proxy;若对象存在循环引用,直接代理会导致无限递归或栈溢出。
- WeakMap 的 key 必须是对象,天然支持按引用去重
- 可在代理前先检测是否已在缓存中,有则直接返回,不新建
- 对原始值(string/number/boolean/symbol)和不可扩展对象跳过代理
可控的代理层级与边界控制
并非所有嵌套都需要代理。可通过配置限制代理深度,或仅对特定字段名(如 children、data、items)启用懒加载。
- 在 handler 中加入 depth 计数或路径白名单逻辑
- 例如:只对 prop === 'children' 且值为数组时做懒代理,其余走原值
- 也可结合 Symbol 标记(如 obj[Symbol.for('lazy')] = true)显式声明需懒加载
与 JSON 数据流配合优化首屏
服务端返回的嵌套 JSON 在前端解析后,初始只代理顶层,深层字段保持 plain object;直到用户展开某节点才触发子级代理。
- 搭配虚拟滚动或树组件的展开事件,按需激活对应子树代理
- 可封装成 createLazyProxy(data, options),options 支持 onAccess 回调用于埋点或预加载
- 注意:Proxy 无法拦截 for...in、Object.keys() 等枚举操作,如需支持需配合 ownKeys + enumerate 等 trap 组合











