应使用WeakMap记录已冻结对象以避免无限递归,优先冻结顶层对象,必要时用Proxy替代深冻结。Object.freeze不处理循环引用,手动深冻结需去重;WeakMap可安全标记对象状态;对循环结构宜解构或截断后再冻结。
直接冻结带有循环引用的对象会触发无限递归,导致栈溢出。根本原因在于 Object.freeze 本身不处理循环引用,而如果你在 freeze 前手动遍历对象(比如深冻结逻辑),又没做引用去重,就会卡死。
实现深冻结时,必须跳过已冻结过的引用。WeakMap 是理想工具,它能以对象为键、标记状态,且不影响垃圾回收。
Object.freeze 后,立即存入 WeakMap绝大多数场景不需要深冻结。循环引用本身不是问题,问题常出在误以为“必须全冻住”。
Object.defineProperty 配合 writable: false 控制单个属性如果确实需要冻结整个结构,先做一次安全遍历,剥离或标记循环点。
{ __circular: true })如果目标是“阻止意外修改”,Proxy 可提供更可控、可中断的拦截能力。
set、defineProperty 等陷阱,统一拒绝写操作=== 返回 false),且某些 API(如 JSON.stringify)可能无法直接处理