WeakRef

翻译不完整。 请帮助我们翻译这篇文章!

WeakRef对象允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被GC回收

Description

一个WeakRef对象包括一个对一个对象的弱引用,这个弱引用被称为该WeakRef对象的target或者是referent。对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为。而与此相反的,一个普通的引用(默认是强引用)会将与之对应的对象保存在内存中。只有当该对象没有任何的强引用时,JavaScript引擎GC才会销毁该对象并且回收该对象所占的内存空间。如果上述情况发生了,那么你就无法通过任何的弱引用来获取该对象。

Note: 在使用前请阅读Avoid where possible,对于WeakRef对象的使用要慎重考虑,能不使用就尽量不要使用

构造函数

WeakRef()
创建一个WeakRef对象

实例方法

WeakRef.prototype.deref()
返回当前实例的WeakRef对象所绑定的target对象,如果该target对象已被GC回收则返回undefined

为什么尽量避免使用

正确使用WeakRef对象需要仔细的考虑,并且这应该是尽可能的避免使用。避免依赖于规范没有保证的任何特定行为也是十分重要的。何时、如何以及是否发生垃圾回收取决于任何给定JavaScript引擎的实现。GC在一个JavaScript引擎中的行为有可能在另一个JavaScript引擎中的行为大相径庭,或者甚至在同一类引擎,不同版本中GC的行为都有可能有较大的差距。GC目前还是JavaScript引擎实现者不断改进和改进解决方案的一个难题。

以下是WeakRef提案的作者在其解释文件(explainer document)中提出的一些具体观点

Garbage collectors are complicated. If an application or library depends on GC cleaning up a WeakRef or calling a finalizer [cleanup callback] in a timely, predictable manner, it's likely to be disappointed: the cleanup may happen much later than expected, or not at all. Sources of variability include:

  • One object might be garbage-collected much sooner than another object, even if they become unreachable at the same time, e.g., due to generational collection.
  • Garbage collection work can be split up over time using incremental and concurrent techniques.
  • Various runtime heuristics can be used to balance memory usage, responsiveness.
  • The JavaScript engine may hold references to things which look like they are unreachable (e.g., in closures, or inline caches).
  • Different JavaScript engines may do these things differently, or the same engine may change its algorithms across versions.
  • Complex factors may lead to objects being held alive for unexpected amounts of time, such as use with certain APIs.

Notes on WeakRefs

关于WeakRefs的一些说明

  • 如果您的代码刚刚为目标对象创建了WeakRef,或者从WeakRef的deref方法获取了目标对象,在当前JavaScript job (包括在脚本作业末尾运行的任何promise reaction作业) 结束之前,不会回收该目标对象。也就是说,您只能“看到”在事件循环的两次循环之间回收的对象。这主要是为了避免在代码中显示任何给定JavaScript引擎的GC行为 ------ 因为如果不这样的话,那么人们会根据这个行为来编写代码,而当GC的行为改变时,就会造成不可预知的后果。(GC是一个棘手的问题;JavaScript引擎实现者依然不断地改进和改进它的工作方式)
  • 如果多个WeakRefs 有相同的目标,那么他们的target对象是一样的。对其中一个调用deref的结果将与对另一个调用deref的结果匹配(在同一个作业中),您不会从其中一个获取目标对象,而是从另一个获取未定义的对象。
  • 如果一个对象是WeakRef的target,又是in a FinalizationRegistry,那么该target就会在调用与注册表关联的任何清理回调之前或者同时被清理。如果清理回调调用对象的WeakRef上的deref,它将收到undefined
  • 你不能更改WeakRef的target,它将始终是第一次指定的target或者在回收该target时会定义
  • WeakRef可能永远不会从deref返回undefined,即使没有什么东西能很好地保存target,因为GC可能永远不会决定回收对象。

Examples

Using a WeakRef object

This example starts a counter shown in a DOM element, stopping when the element doesn't exist anymore:

class Counter {
  constructor(element) {
    // Remember a weak reference to the DOM element
    this.ref = new WeakRef(element);
    this.start();
  }

  start() {
    if (this.timer) {
      return;
    }

    this.count = 0;

    const tick = () => {
      // Get the element from the weak reference, if it still exists
      const element = this.ref.deref();
      if (element) {
        element.textContent = ++this.count;
      } else {
        // The element doesn't exist anymore
        console.log("The element is gone.");
        this.stop();
        this.ref = null;
      }
    };

    tick();
    this.timer = setInterval(tick, 1000);
  }

  stop() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = 0;
    }
  }
}

const counter = new Counter(document.getElementById("counter"));
counter.start();
setTimeout(() => {
  document.getElementById("counter").remove();
}, 5000);

Specifications

Specification
WeakRefs proposal

Browser compatibility

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
WeakRefChrome Full support 84Edge Full support 84Firefox Full support 79IE No support NoOpera No support NoSafari No support NoWebView Android Full support 84Chrome Android Full support 84Firefox Android Full support 79Opera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs Full support 13.0.0
Disabled
Full support 13.0.0
Disabled
Disabled From version 13.0.0: this feature is behind the --harmony-weak-refs runtime flag.
WeakRef() constructorChrome Full support 84Edge Full support 84Firefox Full support 79IE No support NoOpera No support NoSafari No support NoWebView Android Full support 84Chrome Android Full support 84Firefox Android Full support 79Opera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs Full support 13.0.0
Disabled
Full support 13.0.0
Disabled
Disabled From version 13.0.0: this feature is behind the --harmony-weak-refs runtime flag.
derefChrome Full support 84Edge Full support 84Firefox Full support 79IE No support NoOpera No support NoSafari No support NoWebView Android Full support 84Chrome Android Full support 84Firefox Android Full support 79Opera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs Full support 13.0.0
Disabled
Full support 13.0.0
Disabled
Disabled From version 13.0.0: this feature is behind the --harmony-weak-refs runtime flag.

Legend

Full support  
Full support
No support  
No support
User must explicitly enable this feature.
User must explicitly enable this feature.

See also