闭包不能监控篡改,而是通过收口读写、校验输入、阻断引用暴露来实现防篡改:私有变量不出现在返回对象属性中,所有访问必须经由带类型/范围校验的get/set方法,对象值需深拷贝,禁止返回原始引用或副本。

闭包本身不能主动“监控”篡改行为,它只提供访问控制路径。所谓“监控非法篡改”,本质是拒绝非法写入 + 阻断隐式读取,靠的是在访问器函数中嵌入校验逻辑与隔离策略,而非实时检测已发生的修改。
核心思路:把所有读写都收口到闭包内方法
私有数据必须完全不出现在返回对象的属性上,也不能被任何方法以 this、return this._val 或 { value } 等方式暴露原始引用。所有交互只能通过你明确定义的 get 和 set 方法进行。
- 外部无法用
obj.value、obj['value']或Object.keys(obj)查到私有字段 - 没有
Object.defineProperty模拟的“假私有”属性(它只是配置描述符,值仍可枚举或重写) - 不返回对象副本(如
{ data: privateData }),否则副本一出闭包就失去防护意义
set 方法中嵌入类型/范围/合法性校验
这是防篡改最关键的一步。不是等值被改了再报警,而是从源头拦截不合规输入。
对设计或页面进行 WCAG 2.1 AA 无障碍审计。触发关键词:“audit accessibility”、 “check a11y”、 “is this accessible?” 或在审查设计时使用。
- 检查类型:
typeof newValue === 'number'、Array.isArray(newValue) - 检查边界:
newValue >= 0 && newValue - 拒绝危险值:
newValue !== undefined && typeof newValue !== 'function' && newValue !== window - 对对象类值做深拷贝:
JSON.parse(JSON.stringify(newValue))或structuredClone(newValue),防止外部通过引用直接改内部状态
get 方法不返回原始引用,只提供安全快照
即使允许读取,也要确保读出来的数据无法反向污染源。
- 基础类型(string/number/boolean)直接返回,无风险
- 对象/数组必须返回副本,不能返回
state[key]原始引用 - 可选增强:对返回副本调用
Object.freeze()(注意是浅冻结),阻止后续误赋值 - 绝不实现
toString()、valueOf()、Symbol.toPrimitive等可能泄露值的接口
额外加固:避免调试器友好型泄露
开发环境里,Chrome DevTools 的 console.dir() 能看到闭包变量,这不是漏洞,但可降低信息暴露面:
- 不在闭包内定义调试用的
debug()方法或_dump()接口 - 避免在
get中返回带toString的包装对象(如new Number(value)) - 生产环境可通过代码混淆进一步模糊变量名(如
_a代替_value),但不改变逻辑










