Proxy 实现属性访问日志记录的核心是拦截 get 和 set 操作,通过 Reflect 转发保证原行为,记录 key、值、上下文,过滤私有/内置/Symbol 属性,并支持配置化与嵌套代理。

用 Proxy 实现属性访问日志记录,核心是拦截 get 和 set 操作,在触发时打印或收集相关信息。
基础日志代理:捕获读写操作
创建一个包裹目标对象的 Proxy,通过 get 和 set trap 记录每次属性访问。注意传入正确的 receiver(通常是 proxy 本身),避免丢失 this 绑定。
- 在
get中记录读取的 key、当前值、所属对象 - 在
set中记录写入的 key、新值,并返回 true 表示赋值成功 - 使用
Reflect.get/set转发操作,保证原行为不变
带上下文的日志:区分访问来源
单纯记录 key 不够,有时需知道谁在读/写——比如调试深层嵌套或链式调用。可在日志中加入简单堆栈线索(如 new Error().stack.split('\n')[2]),或配合闭包保存调用标识。
- 不建议在生产环境频繁生成完整 stack,影响性能
- 开发阶段可加简短 caller 提示,例如函数名或文件行号片段
- 对 getter/setter 属性,日志应明确标注“通过 accessor 访问”
过滤与控制:避免日志爆炸
默认拦截所有属性会带来大量冗余输出,尤其处理数组、内置方法或 Symbol 属性时。应主动过滤无关项。
立即学习“Java免费学习笔记(深入)”;
- 跳过以
_开头的私有属性(约定)、__proto__、constructor等内置属性 - 忽略 Symbol 类型的 key(除非特别关注)
- 提供开关(如
enableLog: boolean)动态启停日志
实用封装:可复用的 logger 工具函数
把逻辑抽成函数,支持传入配置,方便多处复用:
- 接受 target 对象和 options(如
includeKeys、excludeKeys、onGet回调) - 返回代理对象的同时,暴露
clearLogs()或getHistory()方法 - 对嵌套对象递归代理需谨慎——避免无限循环,可用 WeakMap 缓存已代理对象


















