对象的扩展操作是指将对象从“可扩展”变为“不可扩展”的过程,即阻止后续添加新属性;proxy 的 preventextensions trap 在调用 object.preventextensions(proxy) 时触发,需返回布尔值以决定是否成功禁止扩展,并须与目标对象的可扩展性语义保持一致。

JavaScript 中 Proxy 可以通过 preventExtensions 拦截对象的扩展操作,即阻止后续向对象添加新属性(包括使用 Object.preventExtensions() 或直接赋值新增属性)。
什么是对象的扩展操作?
对象扩展指的是让对象从“可扩展”变为“不可扩展”的过程。一旦对象被设为不可扩展,就不能再添加新属性(但已有属性仍可修改或删除)。原生方法是 Object.preventExtensions(obj),而 Proxy 能在该操作发生时介入并自定义行为。
用 preventExtensions 捕获扩展禁用请求
Proxy 的 preventExtensions trap 在调用 Object.preventExtensions(proxy) 时触发。它必须返回布尔值:返回 true 表示成功禁止扩展;返回 false 会抛出 TypeError(除非目标对象本身已不可扩展)。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 该 trap 不会自动阻止扩展,只是提供拦截时机,是否真正禁止由你返回的布尔值决定
- 返回
true后,后续对 proxy 添加新属性(如proxy.newProp = 1)在严格模式下会静默失败(非严格模式不报错但无效) - 目标对象(target)若本身已不可扩展,trap 返回
false也会报错 —— Proxy 必须保持与目标一致的可扩展性语义
实际例子:记录并控制扩展行为
下面是一个常见用法:当有人试图禁止扩展时打印日志,并只允许在特定条件下生效:
const target = {};
const handler = {
preventExtensions(target) {
console.log('有人试图禁止扩展这个对象');
// 可以根据条件放行或拒绝
if (someCondition()) {
return Reflect.preventExtensions(target);
}
return false; // 拒绝,抛出 TypeError
}
};
const proxy = new Proxy(target, handler);
Object.preventExtensions(proxy); // 触发 trap
注意:不能拦截“隐式”扩展
Proxy 的 preventExtensions 只响应显式的 Object.preventExtensions() 调用,不拦截以下行为:
- 直接给 proxy 新增属性(如
proxy.x = 1)—— 这走的是settrap,不是扩展操作 -
Object.seal()或Object.freeze()—— 它们内部会先调用preventExtensions,所以会被捕获,但它们还额外调用defineProperty和getOwnPropertyDescriptor等 trap - 非 Proxy 对象的扩展操作 —— Proxy 只能代理自己包装的对象
不复杂但容易忽略:preventExtensions 是唯一专门针对“禁止扩展”这一语义的 trap,和其他属性操作无关,用对场景才能精准控制对象生命周期。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










