Proxy.revocable()

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

¥The Proxy.revocable() static method creates a revocable Proxy object.

语法

¥Syntax

js
Proxy.revocable(target, handler)

参数

¥Parameters

target

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

handler

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

返回值

¥Return value

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

¥A plain object with the following two properties:

proxy

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

revoke

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

描述

¥Description

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

¥The Proxy.revocable() factory function is the same as the Proxy() constructor, except that in addition to creating a proxy object, it also creates a revoke function that can be called to disable the proxy. The proxy object and the revoke function are wrapped in a plain object.

revoke 函数不带任何参数,也不依赖于 this 值。创建的 proxy 对象作为 私有属性 附加到 revoke 函数,revoke 函数在调用时会对其自身进行访问(从外部无法观察到私有属性的存在,但它对垃圾收集的发生方式有影响)。proxy 对象未在 revoke 函数的 closure 内捕获(如果 revoke 仍然存在,这将使 proxy 的垃圾回收变得不可能)。

¥The revoke function does not take any parameters, nor does it rely on the this value. The created proxy object is attached to the revoke function as a private property that the revoke function accesses on itself when called (the existence of the private property is not observable from the outside, but it has implications on how garbage collection happens). The proxy object is not captured within the closure of the revoke function (which will make garbage collection of proxy impossible if revoke is still alive).

调用 revoke() 函数后,代理变得不可用:处理程序的任何陷阱都会抛出 TypeError。一旦代理被撤销,它就保持撤销状态,再次调用 revoke() 没有任何效果 - 事实上,调用 revoke() 会将 proxy 对象与 revoke 函数分离,因此 revoke 函数将根本无法再次访问代理。如果代理没有在其他地方被引用,那么它将有资格进行垃圾收集。revoke 函数还将 targethandlerproxy 分离,因此如果 target 在其他地方没有被引用,即使它的代理仍然存在,它也将符合垃圾回收的条件,因为不再有一种方法可以与目标对象进行有意义的交互 。

¥After the revoke() function gets called, the proxy becomes unusable: any trap to a handler throws a TypeError. Once a proxy is revoked, it remains revoked, and calling revoke() again has no effect — in fact, the call to revoke() detaches the proxy object from the revoke function, so the revoke function will not be able to access the proxy again at all. If the proxy is not referenced elsewhere, it will then be eligible for garbage collection. The revoke function also detaches target and handler from the proxy, so if target is not referenced elsewhere, it will also be eligible for garbage collection, even when its proxy is still alive, since there's no longer a way to meaningfully interact with the target object.

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

¥Letting users interact with an object through a revocable proxy allows you to control the lifetime of the object exposed to the user — you can make the object garbage-collectable even when the user is still holding a reference to its proxy.

示例

¥Examples

使用 Proxy.revocable()

¥Using 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

规范

Specification
ECMAScript Language Specification
# sec-proxy.revocable

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看

¥See also