WeakRef(弱参考)

基线 广泛可用

此功能已得到很好的建立,可在许多设备和浏览器版本中使用。从那时起,它就可以跨浏览器使用了 2021年4月.

A类WeakRef(弱参考)对象允许您保留对另一个对象的弱引用,而不会阻止该对象被垃圾收集。

描述

A类WeakRef(弱参考)对象包含对对象的弱引用,称为目标参照物.A型弱参考对象的引用不会阻止垃圾收集器回收该对象。相反,正常(或坚强的)引用将对象保存在内存中。当对象不再具有任何强引用时,JavaScript引擎的垃圾收集器可能会销毁该对象并回收其内存。如果发生这种情况,就无法再从弱引用中获取对象。

因为未注册符号也可以回收垃圾,它们还可以用作WeakRef(弱参考)对象。然而,这种情况的用例是有限的。

尽可能避免

正确使用WeakRef(弱参考)仔细考虑,尽可能避免。避免依赖规范未保证的任何特定行为也很重要。垃圾回收何时、如何以及是否发生取决于任何给定JavaScript引擎的实现。您在一个引擎中观察到的任何行为在另一个引擎、同一引擎的另一个版本中,甚至在同一引擎相同版本的稍微不同的情况下可能会有所不同。垃圾收集是JavaScript引擎实现者不断改进解决方案的一个难题。

以下是作者在建议引入的WeakRef(弱参考):

垃圾收集器都很复杂。如果应用程序或库依赖GC清理WeakRef或以及时、可预测的方式调用终结器[cleanup callback],则可能会令人失望:清理可能会比预期晚很多,或者根本不会发生。可变性的来源包括:

  • 一个对象可能比另一个对象更快地被垃圾收集,即使它们同时变得无法访问,例如,由于分代收集。
  • 垃圾收集工作可以使用增量和并发技术随时间分割。
  • 可以使用各种运行时启发式方法来平衡内存使用和响应能力。
  • JavaScript引擎可能会保存对看起来无法访问的内容的引用(例如,在闭包或内联缓存中)。
  • 不同的JavaScript引擎可能会以不同的方式执行这些操作,或者同一个引擎可能会跨版本更改其算法。
  • 复杂的因素可能会导致对象在意想不到的时间内保持活动状态,例如与某些API一起使用。

关于WeakRefs的注释

  • 如果您的代码刚刚创建了WeakRef(弱参考)或已从WeakRef(弱参考)废弃的方法,则在当前JavaScript结束之前不会回收该目标对象工作(包括在脚本作业结束时运行的任何承诺反应作业)。也就是说,您只能“看到”在事件循环的两次循环之间回收的对象。这主要是为了避免在代码中显示任何给定JavaScript引擎的垃圾收集器的行为,因为如果是这样的话,人们就会依赖该行为来编写代码,而当垃圾收集器行为发生变化时,该行为就会中断。(垃圾收集是一个难题;JavaScript引擎实现者正在不断完善和改进其工作方式。)
  • 如果有多个WeakRef(弱参考)我们有相同的目标,他们彼此一致。调用的结果放弃其中一个将匹配调用结果放弃在另一个(在同一个作业中)上,您不会从其中一个获取目标对象,但未定义来自另一个。
  • 如果WeakRef(弱参考)也位于定案注册表,的WeakRef(弱参考)的目标同时或在调用与注册表关联的任何清理回调之前被清除;如果您的清理回调调用放弃在上WeakRef(弱参考)对于对象,它将接收未定义.
  • 无法更改的目标WeakRef(弱参考),它将始终是原始目标对象或未定义当目标被回收时。
  • A类WeakRef(弱参考)可能永远不会回来未定义放弃,即使没有什么东西可以牢牢地控制目标,因为垃圾收集器可能永远不会决定回收对象。

施工单位

弱参考()

创建新的WeakRef(弱参考)对象。

实例属性

这些属性定义于WeakRef.原型并由所有人共享WeakRef(弱参考)实例。

WeakRef.原型.结构 可选

创建实例对象的构造函数。对于WeakRef(弱参考)实例,初始值为WeakRef(弱参考)构造函数。

注:该属性在规范中标记为“标准可选”,这意味着一致的实现可能不会暴露建造师属性。这可以防止任意代码获取WeakRef(弱参考)构造函数并能够观察垃圾收集。然而,默认情况下,所有主要引擎都会公开它。

WeakRef.原型[Symbol.toStringTag]

的初始值[Symbol.toStringTag]属性是字符串“弱参考”。此属性用于Object.prototype.toString().

实例方法

WeakRef.prototype.deref()

返回WeakRef(弱参考)对象的目标对象,或未定义如果目标对象已被回收。

示例

使用WeakRef对象

此示例启动DOM元素中显示的计数器,当该元素不存在时停止:

js公司
类计数器{构造函数(元素){//记住对DOM元素的弱引用this.ref=新的WeakRef(元素);this.start();}启动(){if(this.timer){回报;}this.count=0;常数刻度=()=>{//从弱引用获取元素(如果它仍然存在)const元素=this.ref.deref();if(元素){element.textContent=++this.count;}其他{//元素不再存在console.log(“元素不见了。”);this.stop();this.ref=空;}};tick();this.timer=setInterval(tick,1000);}停止(){如果(这个计时器){clearInterval(this.timer);this.timer=0;}}}const counter=新计数器(document.getElementById(“计数器”));设置超时(()=>{document.getElementById(“计数器”).remove();}, 5000);

规格

规范
ECMAScript语言规范
#sec-weak-ref对象

浏览器兼容性

BCD表仅在浏览器中加载

另请参见