Proxy 通过 preventExtensions 和 isExtensible 两个 trap 控制对象可扩展性:前者拦截显式禁止扩展操作并需返回布尔值,后者拦截扩展状态查询;二者须协同内部标志(如 isLocked)及 set trap 才能实现动态不可扩展保护。

Proxy 通过 preventExtensions 和 isExtensible 两个 trap 拦截对象的“可扩展性”状态,实现对扩展开关的控制——即决定是否允许新增属性。
preventExtensions:拦截显式禁止扩展的操作
当调用 Object.preventExtensions(proxy) 时,该 trap 被触发。它必须返回布尔值:
- 返回
true表示成功禁止扩展(需同时确保底层 target 也被禁止) - 返回
false会抛出TypeError,拒绝该操作 - 建议用
Reflect.preventExtensions(target)转发,保证语义一致
isExtensible:拦截扩展状态查询
每次调用 Object.isExtensible(proxy) 或内部检查(如 Object.seal 前判断)都会触发此 trap:
- 返回
true表示对象当前仍可扩展 - 返回
false表示已不可扩展 - 该返回值应与实际扩展能力保持同步,否则会导致行为不一致
注意:哪些操作不算“扩展”,不会触发 preventExtensions
Proxy 不拦截隐式扩展行为,这些操作走的是其他 trap:
立即学习“Java免费学习笔记(深入)”;
-
proxy.newProp = value→ 触发settrap,而非 preventExtensions -
Object.seal()/Object.freeze()→ 内部先调用preventExtensions,所以会被捕获;但它们还额外调用defineProperty和getOwnPropertyDescriptor,需一并处理 - 直接添加属性本身不改变 extensibility 状态,只是尝试写入——是否允许,由
settrap 决定
组合使用实现动态不可扩展保护
仅靠单个 trap 不足以完整控制扩展行为,需配合内部状态协同工作:
- 用一个布尔标志(如
isLocked)记录是否已禁止扩展 -
preventExtensions中更新标志,并按需转发或拒绝 -
isExtensible返回该标志值 -
set中检查标志,若已锁定则拒绝新增属性(!target.hasOwnProperty(prop)且!isLocked)


















