proxy 可通过 get 和 has 拦截器实现属性级权限控制:get 中校验读取权限并用 reflect.get 转发,has 中隐藏无权属性的存在性;需配合 ownkeys 和 getownpropertydescriptor 过滤敏感键,注意递归代理嵌套对象及性能优化。

Proxy 可以通过拦截 get 和 has 操作,在读取属性前动态判断访问权限,实现细粒度的属性级控制。
用 get 拦截器做读取权限校验
在 get(target, prop, receiver) 中检查当前用户是否拥有该属性的读取权限。如果无权访问,可返回默认值、抛出错误或屏蔽属性。
- 权限规则可存在对象自身(如
target.__permissions)、外部配置表,或调用鉴权函数(如canRead(user, prop)) - 注意:需用
Reflect.get()转发合法访问,避免丢失原型链或 getter 行为 - 对私有属性(如以
_或#开头)可统一拒绝,或按角色白名单放行
用 has 拦截器隐藏属性存在性
has(target, prop) 控制 prop in proxy 和 with 语句中的属性可见性。无权访问的属性可让它“不存在”,增强封装性。
- 返回
false后,in操作符、for...in循环、Object.keys()(不直接拦截但受ownKeys影响)均不可见该属性 - 若同时拦截
get和has,需保持逻辑一致——has返回true却在get中拒绝,可能引发意外行为
结合 ownKeys 和 enumerate 做属性枚举控制
ownKeys 决定 Object.getOwnPropertyNames()、Reflect.ownKeys() 等返回哪些键;enumerate(已废弃,现代环境不用)曾影响 for...in,现由 ownKeys + getOwnPropertyDescriptor 共同决定。
- 在
ownKeys中过滤掉无权列出的属性,让敏感字段彻底“不可见” - 配合
getOwnPropertyDescriptor拦截,确保Object.getOwnPropertyDescriptor(proxy, 'secret')也返回undefined或抛错 - 注意:某些方法(如
JSON.stringify)会跳过不可枚举属性,若需完全隔离,还需重写toJSON或拦截get
实际使用时的关键细节
权限控制不是只靠 Proxy 就能闭环,需和用户上下文、权限模型配合设计。
- Proxy 是浅代理,嵌套对象需递归代理或按需代理,否则内层属性不受控
- 避免在拦截器中做耗时鉴权(如查数据库),应预加载权限缓存或使用同步策略
- 对数组或内置类型(如
Date、Map)代理要谨慎,部分操作可能绕过拦截或触发意外副作用 - 调试时可用
console.log或debugger在拦截器中观察访问路径,但上线应移除
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











