页面模式偏好

26 内存管理

26.1 WeakRef 对象

WeakRef 是一种用于引用目标对象或符号而不会阻止其被垃圾回收的对象。如果目标尚未被垃圾回收回收,则可以对 WeakRef 进行解引用以访问目标值。

26.1.1 WeakRef 构造函数

WeakRef 构造函数:

  • 是 %WeakRef%。
  • 是全局对象的 "WeakRef" 属性的初始值。
  • 作为构造函数调用时,创建并初始化新的 WeakRef。
  • 不旨在作为函数调用,并且以这种方式调用时会抛出异常。
  • 可以用作类定义的 extends 子句中的值。希望继承指定 WeakRef 行为的子类构造函数必须包含对 WeakRef 构造函数的 super 调用,以创建并初始化具有支持 WeakRef.prototype 内置方法所必需内部状态的子类实例。

26.1.1.1 WeakRef ( target )

调用时,此函数执行以下步骤:

  1. 如果 NewTarget 是 undefined,则抛出 TypeError 异常。
  2. 如果 CanBeHeldWeakly(target) 是 false,则抛出 TypeError 异常。
  3. 令 weakRef 为 ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRef.prototype%", « [[WeakRefTarget]] »)。
  4. 执行 AddToKeptObjects(target)。
  5. 将 weakRef.[[WeakRefTarget]] 设置为 target。
  6. 返回 weakRef。

26.1.2 WeakRef 构造函数的属性

WeakRef 构造函数:

26.1.2.1 WeakRef.prototype

WeakRef.prototype 的初始值是 WeakRef 原型对象。

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

26.1.3 WeakRef 原型对象的属性

WeakRef 原型对象:

  • 是 %WeakRef.prototype%。
  • 具有 [[Prototype]] 内部槽,其值是 %Object.prototype%。
  • 是普通对象。
  • 不具有 [[WeakRefTarget]] 内部槽。

26.1.3.1 WeakRef.prototype.constructor

WeakRef.prototype.constructor 的初始值是 %WeakRef%。

26.1.3.2 WeakRef.prototype.deref ( )

调用时,此方法执行以下步骤:

  1. 令 weakRef 为 this value。
  2. 执行 ? RequireInternalSlot(weakRef, [[WeakRefTarget]])。
  3. 返回 WeakRefDeref(weakRef)。
注

如果 WeakRef 返回的 target 值不是 undefined,那么在当前 ECMAScript 代码执行完成之前,不应对该 target 值进行垃圾回收。AddToKeptObjects 操作用于确保保持读取一致性。

let target = { foo() {} };
let weakRef = new WeakRef(target);

// ... 稍后 ...

if (weakRef.deref()) {
  weakRef.deref().foo();
}

在上述示例中,如果第一次 deref 的求值结果不是 undefined,那么第二次 deref 的求值结果也不可能是 undefined。

26.1.3.3 WeakRef.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是 String 值 "WeakRef"。

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

26.1.4 WeakRef 抽象操作

26.1.4.1 WeakRefDeref ( weakRef )

抽象操作 WeakRefDeref,接收参数 weakRef (WeakRef);返回值:ECMAScript 语言值。 调用时执行以下步骤:

  1. 令 target 为 weakRef.[[WeakRefTarget]]。
  2. 如果 target 不是 empty,则
    1. 执行 AddToKeptObjects(target)。
    2. 返回 target。
  3. 返回 undefined。
注

此抽象操作与 WeakRef.prototype.deref 分开定义,仅仅是为了能够简洁地定义活性。

26.1.5 WeakRef 实例的属性

WeakRef 实例是从 WeakRef 原型对象继承属性的普通对象。WeakRef 实例还具有 [[WeakRefTarget]] 内部槽。

26.2 FinalizationRegistry 对象

FinalizationRegistry 是一种管理清理操作的注册和取消注册的对象,这些清理操作会在目标对象和符号被垃圾回收时执行。

26.2.1 FinalizationRegistry 构造函数

FinalizationRegistry 构造函数:

  • 是 %FinalizationRegistry%。
  • 是全局对象的 "FinalizationRegistry" 属性的初始值。
  • 作为构造函数调用时,创建并初始化新的 FinalizationRegistry。
  • 不旨在作为函数调用,并且以这种方式调用时会抛出异常。
  • 可以用作类定义的 extends 子句中的值。希望继承指定 FinalizationRegistry 行为的子类构造函数必须包含对 FinalizationRegistry 构造函数的 super 调用,以创建并初始化具有支持 FinalizationRegistry.prototype 内置方法所必需内部状态的子类实例。

26.2.1.1 FinalizationRegistry ( cleanupCallback )

调用时,此函数执行以下步骤:

  1. 如果 NewTarget 是 undefined,则抛出 TypeError 异常。
  2. 如果 IsCallable(cleanupCallback) 是 false,则抛出 TypeError 异常。
  3. 令 finalizationRegistry 为 ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationRegistry.prototype%", « [[Realm]], [[CleanupCallback]], [[Cells]] »)。
  4. 令 activeFunc 为活动函数对象。
  5. 将 finalizationRegistry.[[Realm]] 设置为 activeFunc.[[Realm]]。
  6. 将 finalizationRegistry.[[CleanupCallback]] 设置为 HostMakeJobCallback(cleanupCallback)。
  7. 将 finalizationRegistry.[[Cells]] 设置为新的空 List。
  8. 返回 finalizationRegistry。

26.2.2 FinalizationRegistry 构造函数的属性

FinalizationRegistry 构造函数:

26.2.2.1 FinalizationRegistry.prototype

FinalizationRegistry.prototype 的初始值是 FinalizationRegistry 原型对象。

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

26.2.3 FinalizationRegistry 原型对象的属性

FinalizationRegistry 原型对象:

  • 是 %FinalizationRegistry.prototype%。
  • 具有 [[Prototype]] 内部槽,其值是 %Object.prototype%。
  • 是普通对象。
  • 不具有 [[Cells]] 和 [[CleanupCallback]] 内部槽。

26.2.3.1 FinalizationRegistry.prototype.constructor

FinalizationRegistry.prototype.constructor 的初始值是 %FinalizationRegistry%。

26.2.3.2 FinalizationRegistry.prototype.register ( target, heldValue [ , unregisterToken ] )

调用时,此方法执行以下步骤:

  1. 令 finalizationRegistry 为 this value。
  2. 执行 ? RequireInternalSlot(finalizationRegistry, [[Cells]])。
  3. 如果 CanBeHeldWeakly(target) 是 false,则抛出 TypeError 异常。
  4. 如果 SameValue(target, heldValue) 是 true,则抛出 TypeError 异常。
  5. 如果 CanBeHeldWeakly(unregisterToken) 是 false,则
    1. 如果 unregisterToken 不是 undefined,则抛出 TypeError 异常。
    2. 将 unregisterToken 设置为 empty。
  6. 令 cell 为 Record { [[WeakRefTarget]]: target, [[HeldValue]]: heldValue, [[UnregisterToken]]: unregisterToken }。
  7. 将 cell 追加到 finalizationRegistry.[[Cells]]。
  8. 返回 undefined。
注

根据本规范中的算法和定义,当 finalizationRegistry.[[Cells]] 包含 cell 时,cell.[[HeldValue]] 是存活的;不过,这并不一定意味着 cell.[[UnregisterToken]] 或 cell.[[Target]] 是存活的。例如,将对象自身注册为其取消注册 token 并不会使该对象永远保持存活。

26.2.3.3 FinalizationRegistry.prototype.unregister ( unregisterToken )

调用时,此方法执行以下步骤:

  1. 令 finalizationRegistry 为 this value。
  2. 执行 ? RequireInternalSlot(finalizationRegistry, [[Cells]])。
  3. 如果 CanBeHeldWeakly(unregisterToken) 是 false,则抛出 TypeError 异常。
  4. 令 removed 为 false。
  5. 对 finalizationRegistry.[[Cells]] 的每个 Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] } cell,执行
    1. 如果 cell.[[UnregisterToken]] 不是 empty 且 SameValue(cell.[[UnregisterToken]], unregisterToken) 是 true,则
      1. 从 finalizationRegistry.[[Cells]] 中移除 cell。
      2. 将 removed 设置为 true。
  6. 返回 removed。

26.2.3.4 FinalizationRegistry.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是 String 值 "FinalizationRegistry"。

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

26.2.4 FinalizationRegistry 实例的属性

FinalizationRegistry 实例是从 FinalizationRegistry 原型对象继承属性的普通对象。FinalizationRegistry 实例还具有 [[Cells]] 和 [[CleanupCallback]] 内部槽。