Proxy.revocable()

Baseline 已广泛支持

此功能已成熟,可跨多种设备和浏览器版本使用。自 ⁨2017 年 12 月⁩ 起,在浏览器中均可使用。

Proxy.revocable() 静态方法创建一个可撤销的 Proxy 对象。

语法

js
Proxy.revocable(target, handler)

参数

目标

要用 Proxy 包装的目标对象。它可以是任何类型的对象,包括原生数组、函数,甚至是另一个代理。

handler

一个对象,其属性是函数,这些函数定义了在对 proxy 执行操作时的行为。

返回值

一个具有以下两个属性的普通对象

proxy

一个 Proxy 对象,与使用 new Proxy(target, handler) 调用创建的代理对象完全相同。

revoke

一个不带参数的函数,用于撤销(关闭)proxy

描述

Proxy.revocable() 工厂函数与 Proxy() 构造函数相同,不同之处在于,除了创建一个代理对象外,它还创建了一个 revoke 函数,可以调用该函数来禁用代理。代理对象和 revoke 函数被包装在一个普通对象中。

revoke 函数不接受任何参数,也不依赖于 this 值。创建的 proxy 对象作为 私有字段 附加到 revoke 函数上,revoke 函数在被调用时通过自身访问此私有字段(私有字段的存在从外部是无法观察到的,但它会影响垃圾回收机制的工作方式)。proxy 对象 *不* 会被包含在 revoke 函数的 闭包 中(如果 revoke 仍然存在,这将导致 proxy 无法被垃圾回收)。

在调用 revoke() 函数后,代理将变得不可用:对任何 trap 的访问都会抛出 TypeError。一旦代理被撤销,它将保持撤销状态,再次调用 revoke() 将不起任何作用——事实上,调用 revoke() 会将 proxy 对象与 revoke 函数分离,因此 revoke 函数将无法再次访问该代理。如果代理没有被其他地方引用,它将有资格被垃圾回收。revoke 函数还会将 targethandlerproxy 分离,因此如果 target 没有被其他地方引用,即使其代理仍然存在,它也有资格被垃圾回收,因为已经没有有意义的方式来与目标对象交互了。

允许用户通过一个可撤销的代理与对象进行交互,这使得你可以 控制暴露给用户的对象的生命周期 —— 即使用户仍然持有其代理的引用,你也可以让该对象可被垃圾回收。

示例

使用 Proxy.revocable()

js
const revocable = Proxy.revocable(
  {},
  {
    get(target, name) {
      return `[[${name}]]`;
    },
  },
);
const proxy = revocable.proxy;
console.log(proxy.foo); // "[[foo]]"

revocable.revoke();

console.log(proxy.foo); // TypeError is thrown
proxy.foo = 1; // TypeError again
delete proxy.foo; // still TypeError
typeof proxy; // "object", typeof doesn't trigger any trap

规范

规范
ECMAScript® 2026 语言规范
# sec-proxy.revocable

浏览器兼容性

另见