proxy可通过拦截get、has、ownkeys、getownpropertydescriptor、set和deleteproperty统一管控私有属性:读取返回undefined或报错,in操作返回false,枚举过滤下划线开头属性,设置和删除则拒绝或伪成功。

Proxy 可以在不修改原对象的前提下,统一拦截对私有属性(比如以 _ 开头的属性)的读取、设置、枚举和删除操作,让外部代码“看不见”也“改不了”这些字段。
拦截 get:隐藏私有属性值
当访问 obj._secret 时,get trap 被触发。只需判断属性名是否以 _ 开头,返回 undefined 或抛出错误即可。
- 推荐用
prop.startsWith('_')判断,比prop[0] === '_'更安全(避免空字符串报错) - 不要直接写
target[prop],应优先使用Reflect.get(target, prop, receiver),确保原型链行为一致 - 若想彻底禁止访问,可抛出
Error;若仅隐藏,返回undefined即可
拦截 has:让 in 操作符失效
'_pwd' in proxy 这类判断会触发 has trap。它决定属性是否“存在”于代理对象中。
- 返回
false时,in表达式结果为false,即使目标对象里真有该属性 - 需同时检查
prop in target,避免把合法公有属性也过滤掉 - 典型写法:
return prop[0] !== '_' && prop in target
拦截 ownKeys 和 getOwnPropertyDescriptor:控制 Object.keys 等枚举行为
Object.keys(proxy)、JSON.stringify(proxy) 等会触发 ownKeys;Object.getOwnPropertyDescriptor(proxy, '_x') 会触发 getOwnPropertyDescriptor。
-
ownKeys应返回一个键数组,过滤掉所有私有属性名:Reflect.ownKeys(target).filter(k => !k.startsWith('_')) -
getOwnPropertyDescriptor对私有属性可返回undefined,这样Object.getOwnPropertyDescriptor就查不到它 - 这两项配合
has和get,才能让私有属性在绝大多数场景下“不可见”
拦截 set 和 deleteProperty:阻止修改与删除
用户尝试赋值 proxy._count = 10 或删除 delete proxy._flag 时,分别触发 set 和 deleteProperty。
-
set中检测到私有属性名,可直接return false(赋值失败)或忽略赋值但返回true -
deleteProperty对私有属性返回true即可表示“删除成功”,实际并不删除——这是常见做法,语义上“删不掉”比“删了没用”更清晰 - 注意:必须显式返回
true或false,否则严格模式下会报错











