Spec-Zone.ru › JavaScript

WeakRef

Базовая версия Широко доступно

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и в различных версиях браузеров. Она доступна во всех браузерах с апреля 2021 года.

Объект WeakRef позволяет вам хранить слабую ссылку на другой объект, не препятствуя при этом сборке мусора этого объекта.

Описание

Объект WeakRef содержит слабую ссылку на объект, который называется его целью (target) или референтом (referent). Слабая ссылка на объект — это ссылка, которая не препятствует освобождению объекта сборщиком мусора. В отличие от нее, обычная (или сильная) ссылка удерживает объект в памяти. Когда объект больше не имеет сильных ссылок на него, сборщик мусора движка JavaScript может уничтожить объект и освободить его память. Если это произойдет, вы больше не сможете получить объект по слабой ссылке.

Поскольку незарегистрированные символы также могут быть собраны сборщиком мусора, они могут быть использованы в качестве цели объекта WeakRef. Однако область применения этого ограничена.

Избегайте, где это возможно

Правильное использование WeakRef требует тщательного обдумывания, и его лучше избегать, если это возможно. Также важно избегать зависимости от какого-либо конкретного поведения, не гарантированного спецификацией. Когда, как и происходит ли вообще сборка мусора, зависит от реализации конкретного движка JavaScript. Любое поведение, которое вы наблюдаете в одном движке, может отличаться в другом движке, в другой версии того же движка, или даже в немного иной ситуации с той же версией того же движка. Сборка мусора — это сложная проблема, и разработчики движков JavaScript постоянно совершенствуют и улучшают свои решения.

Вот несколько конкретных моментов, включенных авторами в предложение, которое представило WeakRef:

Сборщики мусора сложны. Если приложение или библиотека полагаются на то, что сборщик мусора своевременно и предсказуемо очистит WeakRef или вызовет финализатор [коллбэк очистки], они, скорее всего, будут разочарованы: очистка может произойти гораздо позже, чем ожидалось, или не произойти вообще. Источники изменчивости включают:

  • Один объект может быть собран гораздо раньше, чем другой, даже если они становятся недостижимыми одновременно, например, из-за поколенческой сборки.
  • Работа по сбору мусора может быть распределена по времени с использованием инкрементальных и параллельных методов.
  • Могут использоваться различные эвристики времени выполнения для балансирования использования памяти и скорости отклика.
  • Движок JavaScript может удерживать ссылки на вещи, которые кажутся недостижимыми (например, в замыканиях или встроенных кешах).
  • Различные движки JavaScript могут выполнять эти действия по-разному, или один и тот же движок может менять свои алгоритмы в разных версиях.
  • Сложные факторы могут приводить к тому, что объекты остаются живыми неожиданно долго, например, при использовании определенных API.

Заметки о WeakRefs

  • Если ваш код только что создал WeakRef для целевого объекта или получил целевой объект из метода deref WeakRef, этот целевой объект не будет освобожден до конца текущей задачи JavaScript (включая любые задачи реакции промисов, которые выполняются в конце задачи скрипта). То есть вы можете «увидеть» освобождение объекта только между итерациями цикла событий. Это сделано в первую очередь для того, чтобы избежать явного проявления поведения сборщика мусора конкретного движка JavaScript в коде — потому что если бы это было так, люди бы писали код, полагаясь на это поведение, которое нарушилось бы при изменении поведения сборщика мусора. (Сборка мусора — это сложная проблема; разработчики движков JavaScript постоянно совершенствуют и улучшают принципы ее работы.)
  • Если несколько WeakRef имеют одну и ту же цель, они согласованы друг с другом. Результат вызова deref для одного из них будет соответствовать результату вызова deref для другого (в одной и той же задаче): вы не получите целевой объект от одного из них, а undefined от другого.
  • Если цель WeakRef также находится в FinalizationRegistry, цель WeakRef очищается одновременно или до вызова любого коллбэка очистки, связанного с реестром; если ваш коллбэк очистки вызывает deref на WeakRef для объекта, он получит undefined.
  • Вы не можете изменить цель WeakRef, это всегда будет только исходный целевой объект или undefined, когда эта цель была освобождена.
  • WeakRef может никогда не вернуть undefined из deref, даже если ничто не удерживает цель сильно, поскольку сборщик мусора может никогда не принять решение об освобождении объекта.

Конструктор

WeakRef()
Создает новый объект WeakRef.

Свойства экземпляра

Эти свойства определены в WeakRef.prototype и являются общими для всех экземпляров WeakRef.

WeakRef.prototype.constructor Optional

Функция-конструктор, создавшая объект-экземпляр. Для экземпляров WeakRef начальным значением является конструктор WeakRef.

Примечание: Это свойство помечено как «нормативно необязательное» (normative optional) в спецификации, что означает, что соответствующая реализация может не предоставлять доступ к свойству constructor. Это предотвращает получение произвольным кодом конструктора WeakRef и возможность отслеживать сборку мусора. Однако все основные движки предоставляют к нему доступ по умолчанию.

WeakRef.prototype[Symbol.toStringTag]
Начальное значение свойства [Symbol.toStringTag] — строка "WeakRef". Это свойство используется в Object.prototype.toString().

Методы экземпляра

WeakRef.prototype.deref()
Возвращает целевой объект объекта WeakRef, или undefined, если целевой объект был освобожден.

Примеры

Использование объекта WeakRef

Этот пример запускает счетчик, отображаемый в элементе DOM, и останавливается, когда элемент перестает существовать:

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"));
setTimeout(() => {
  document.getElementById("counter").remove();
}, 5000);

Спецификации

Спецификация
Спецификация языка ECMAScript® 2027
# sec-weak-ref-objects

Совместимость с браузерами

Десктопные Мобильные Серверные
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
WeakRef
84
84
79
70
14.1
84
79
60
14.5
14.0
84
14.5
1.0.0
1.0
14.6.0
WeakRef
84
84
79
70
14.1
84
79
60
14.5
14.0
84
14.5
1.0.0
1.0
14.6.0
deref
84
84
79
70
14.1
84
79
60
14.5
14.0
84
14.5
1.0.0
1.0
14.6.0

См. также

  • FinalizationRegistry
  • WeakSet
  • WeakMap

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API