26 管理内存

26.1 WeakRef 对象

WeakRef 是一种对象,用于引用目标对象或符号,而不阻止其被垃圾回收。WeakRefs 可以被解引用,以便在目标尚未被垃圾回收回收的情况下允许访问目标值。

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]] 内部槽。
Normative Optional

26.1.3.1 WeakRef.prototype.constructor

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

26.1.3.2 WeakRef.prototype.deref ( )

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

  1. weakRefthis 值。
  2. 执行 ? RequireInternalSlot(weakRef, [[WeakRefTarget]])。
  3. 返回 WeakRefDeref(weakRef)。
Note

如果 WeakRef 返回一个不是 undefinedtarget 值,则在当前 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 )

The abstract operation WeakRefDeref takes argument weakRef (一个 WeakRef,) and returns 一个 ECMAScript 语言值. It performs the following steps when called:

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

抽象操作与 WeakRef.prototype.deref 分开定义,严格来说是为了能够简洁地定义 liveness。

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. fn活动函数对象
  5. finalizationRegistry.[[Realm]] 设置为 fn.[[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. finalizationRegistrythis 值。
  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. cellRecord { [[WeakRefTarget]]: target, [[HeldValue]]: heldValue, [[UnregisterToken]]: unregisterToken }。
  7. cell 追加到 finalizationRegistry.[[Cells]]
  8. 返回 undefined
Note

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

26.2.3.3 FinalizationRegistry.prototype.unregister ( unregisterToken )

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

  1. finalizationRegistrythis 值。
  2. 执行 ? RequireInternalSlot(finalizationRegistry, [[Cells]])。
  3. 如果 CanBeHeldWeakly(unregisterToken) 是 false,抛出 TypeError 异常。
  4. removedfalse
  5. 对于 finalizationRegistry.[[Cells]] 的每个 Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] } cell,执行
    1. 如果 cell.[[UnregisterToken]] 不是 emptySameValue(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]] 内部槽。