Proxy 可实现比 Object.freeze 更强大灵活的只读副本,通过拦截 set/deleteProperty/defineProperty/setPrototypeOf/preventExtensions 等所有修改操作并抛出明确错误,支持数组、Map、Set 等深层只读及惰性代理,兼具开发报错与线上降级能力。

Proxy 可以实现比 Object.freeze 更强大、更灵活的只读副本,关键在于拦截所有可能修改对象的操作,并返回有意义的错误提示(而非静默失败),同时支持嵌套对象、数组、Map/Set 等复杂结构的深层只读控制。
拦截所有写入与原型操作
仅拦截 set 不够——生产环境需阻断 deleteProperty、defineProperty、setPrototypeOf、preventExtensions 等所有可能导致状态变更的 trap。Proxy 的优势在于可统一管控这些行为:
-
set / deleteProperty / defineProperty:一律返回
false并抛出明确错误(如TypeError: Cannot modify readonly object) - setPrototypeOf / preventExtensions / seal / freeze:同样拒绝,避免绕过只读语义
- get:对获取到的引用值(如对象、数组)递归包装为只读 Proxy,实现“惰性深层只读”
支持任意数据类型与嵌套结构
Object.freeze 对数组、Map、Set、Date、RegExp 等无效或不一致;Proxy 可统一处理:
macOS 微信消息自动化工具。通过 GUI 自动化实现:发送消息给指定联系人、读取聊天内容、监控新消息。适用于需要自动化微信操作的场景,如定时发送、批量回复、消息备份等。依赖 peekaboo 进行屏幕截图和 UI 交互。仅支持 macOS。开源地址:https://github.com/chairmanmia...
- 对
Array拦截push、pop、splice等方法(通过gettrap 返回代理后的数组方法) - 对
Map/Set拦截set、delete、clear等实例方法 - 对普通对象/数组,递归代理子属性;对原始值(string/number/boolean)直接返回,无需代理
可配置与可调试的只读策略
生产环境需要区分开发与线上行为:开发时抛错 + 堆栈提示;线上可降级为警告或静默(视安全要求而定)。还可支持白名单字段(如允许某些元数据更新):
- 构造只读 Proxy 时传入配置对象:
{ strict: true, allow: ['__meta'] } - 在
set或deleteProperty中检查 key 是否在白名单,跳过拦截 - 配合
console.warn或监控上报,记录非法修改尝试,辅助排查数据流问题
性能与内存注意事项
Proxy 不会深拷贝,而是“按需代理”,开销可控;但需避免重复代理同一对象:
- 用 WeakMap 缓存已代理的对象,相同原对象多次调用返回同一 Proxy 实例
- 对大型嵌套结构,首次访问深层属性才创建子 Proxy,避免启动时全量遍历
- 避免代理频繁创建/销毁的对象(如 React 组件 state 中的临时对象),应代理源头数据源
不复杂但容易忽略:只读不是目的,而是保障不可变数据流的手段。用 Proxy 替代 Object.freeze 的核心价值,在于它让“只读”成为可观察、可定制、可组合的一等契约,而不是一个静态快照。

















