deleteproperty陷阱需明确定义于handler中并验证逻辑:未定义则直接删除;定义后须返回false拦截关键属性,且需覆盖symbol、原型链及业务字段白/黑名单,并配合has、get实现纵深防御。

识别 deleteProperty 陷阱,关键不是“看它是否存在”,而是观察它是否在代理对象上被明确定义,并且是否对特定属性名做了拦截逻辑。它本身不会自动生效,必须显式写在 handler 对象里,否则 delete 操作就走默认行为(直接删掉)。
确认 deleteProperty 是否被定义
检查你创建 Proxy 时传入的 handler 对象,是否有 deleteProperty 方法:
- 有定义 → 说明该代理已启用删除拦截,需进一步看它的逻辑
- 没定义 → delete 操作会直接作用于 target,不触发任何保护,核心属性可能被删
- 即使定义了,也要看内部是否真的做了判断,比如只对
id、status这类业务关键字段返回false
验证它是否真正拦截了关键属性
不能只看代码,要实测。例如目标对象含 { id: 123, name: "order", amount: 99.9 },可这样验证:
-
delete proxy.id→ 如果返回false且proxy.id仍为123,说明拦截生效 -
delete proxy.amount→ 如果成功返回true且值消失,说明该字段未受保护 - 注意:拦截函数必须显式返回
false才能阻止删除;若没 return 或返回true,删除仍会发生
检查拦截逻辑是否覆盖业务场景
常见疏漏是只拦「自有属性」,却忽略原型链或 Symbol 属性。实际业务中要注意:
- 是否用
Reflect.has(target, key)或target.hasOwnProperty(key)判断关键字段存在性 - 是否处理了 Symbol 类型的 key(比如
Symbol('locked')) - 是否对敏感字段名做了白名单(如
['id', 'createdAt', 'version'])或黑名单(如排除所有以_开头的内部字段) - 是否在拦截中抛出错误(增强调试可见性),而不仅是静默拒绝
配合 has 和 get 陷阱做纵深防御
单靠 deleteProperty 不够稳妥。建议组合使用:
- 用
has陷阱让'id' in proxy始终为true,避免业务代码因误判属性不存在而跳过校验 - 用
get陷阱对读取敏感字段加日志或权限检查,提前暴露异常访问意图 - 在
deleteProperty中调用Reflect.deleteProperty()前,先记录操作者(如通过receiver判断调用上下文)










