ECMAScript | Объекты Слабые Карты (WeakMap Objects)

ECMAScript | Объекты Слабые Карты (WeakMap Objects)

Слабые Карты (WeakMaps) — это коллекции пар ключ/значение, где ключи являются объектами, а значения могут быть произвольными значениями языка ECMAScript. Слабая Карта (WeakMap) может быть запрошена, чтобы увидеть, содержит ли она пару ключ/значение с определенным ключом, но не предусмотрен механизм для перечисления объектов, которые он содержит в качестве ключей. В определенных условиях неактивные объекты удаляются как ключи Слабой Карты (WeakMap), как описано в разделе 9.10.3.

 

Реализация может накладывать произвольно определенную задержку между моментом, когда пара ключ/значение Слабой Карты (WeakMap) становится недоступной, и временем, когда пара ключ/значение удаляется из Слабой Карты (WeakMap). Если бы эта задержка наблюдалась для программы ECMAScript, она была бы источником неопределенности, которая могла бы повлиять на выполнение программы. По этой причине реализация ECMAScript не должна предоставлять никаких средств для наблюдения за ключом Слабой Карты (WeakMap), который не требует, чтобы наблюдатель представлял наблюдаемый ключ.

Слабые Карты (WeakMaps) должны быть реализованы с использованием либо хэш-таблиц, либо других механизмов, которые в среднем обеспечивают время доступа, которое сублинейно зависит от количества пар ключ/значение в коллекции. Структура данных, используемая в этой спецификации, предназначена только для описания требуемой наблюдаемой семантики Слабых Карт (WeakMaps). Она не предназначена для использования в качестве жизнеспособной модели реализации.

Примечание

Слабая Карта (WeakMap) и Слабые Наборы (WeakSets) предназначены для предоставления механизмов динамического связывания состояния с объектом таким образом, чтобы не «расходовать» ресурсы памяти, при отсутствии объектов Слабой Карты (WeakMap) или Слабого Набора (WeakSet), в противном случае чтобы объект стал недоступен и подлежал восстановлению ресурсов со стороны реализации механизмов сборки мусора. Эта характеристика может быть достигнута путем использования инвертированного для каждого объекта сопоставления экземпляров слабой карты с ключами. В качестве альтернативы каждая слабая карта может внутренне хранить свой ключ к сопоставлениям значений, но этот подход требует координации между реализацией Слабой Карты (WeakMap) или Слабого Набора (WeakSet) и Сборщиком Мусора (garbage collector). Следующие ссылки описывают механизм, который может быть полезен для реализации Слабой Карты (WeakMap) и Слабого Набора (WeakSet):

Барри Хейс (Barry Hayes). 1997. Эфемероны: новый механизм завершения. В материалах 12-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям (OOPSLA ’97), А. Майкл Берман (ред.). ACM, Нью-Йорк, Нью-Йорк, США, 176-183, http://doi.acm.org/10.1145/263698.263733.

Александра Баррос (Alexandra Barros), Роберто Иерусалимши (Roberto Ierusalimschy), Устранение циклов в слабых таблицах. Журнал универсальных компьютерных наук — J.UCS, vol. 14, вып. 21, стр. 3481-3497, 2008 г., http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak

 

24.3.1 Конструктор Слабой Карты (The WeakMap Constructor)

Конструктор WeakMap:

  • является %WeakMap%.
  • является начальным значением свойства «WeakMap» глобального объекта.
  • создает и инициализирует новый Слабой Карты (WeakMap) при вызове в качестве конструктора.
  • не предназначен для вызова как функция и вызовет исключение при таком вызове.
  • может использоваться как значение в предложении extends определения класса. Конструкторы подкласса, которые намереваются наследовать указанное поведение Слабой Карты (WeakMap) , должны включать вызов super для конструктора WeakMap для создания и инициализации экземпляра подкласса с внутренним состоянием, необходимым для поддержки встроенных методов WeakMap.prototype.

 

24.3.1.1 WeakMap ( [ iterable ] )

Когда функция WeakMap вызывается с необязательным аргументом iterable, выполняются следующие шаги:

1. Если NewTarget является undefined (не определен), выбросить исключение TypeError.
2. Пусть map будет ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »).
3. Установите map.[[WeakMapData]] в новый пустой Список.
4. Если iterable является undefined (не определен) или равна нулю, вернуть map.
5. Пусть adder будет ? Получить Get(map, "set").
6. Вернуть ? AddEntriesFromIterable(map, iterable, adder).
Примечание

Если параметр iterable присутствует, ожидается, что это будет объект, реализующий метод @@iterator, который возвращает объект-итератор, который создает двухэлементный объект, подобный массиву, первый элемент которого является значением, которое будет использоваться в качестве ключа Слабой Карты (WeakMap) и второй элемент которого — значение, которое нужно связать с этим ключом.

 

24.3.2 Свойства конструктора WeakMap (Properties of the WeakMap Constructor)

Конструктор Слабой Карты (WeakMap):

  • имеет внутренний слот [[Prototype]], значение которого — %Function.prototype%.
  • обладает следующими свойствами:

 

24.3.2.1 WeakMap.prototype

Начальным значением WeakMap.prototype является объект-прототип Слабой Карты (WeakMap prototype object).

Это свойство имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}.

 

24.3.3 Свойства объекта прототипа Слабой Карты (Properties of the WeakMap Prototype Object)

Объект-прототип Слабой Карты:

  • является %WeakMap.prototype%.
  • имеет внутренний слот [[Prototype]], значение которого равно %Object.prototype%.
  • это обычный объект.
  • не имеет внутреннего слота [[WeakMapData]].

 

24.3.3.1 WeakMap.prototype.constructor

Начальное значение WeakMap.prototype.constructor является %WeakMap%.

 

24.3.3.2 WeakMap.prototype.delete ( key )

Выполняются следующие шаги:

1. Пусть M будет значением this.
2. Выполнить ? RequireInternalSlot(M, [[WeakMapData]]).
3. Пусть записями entries будет Список M.[[WeakMapData]].
4. Если Тип(key) не является Объектом, вернуть false.
5. Для каждой Записи {[[Key]], [[Value]]} p из записей entries выполните
  а. Если p.[[Key]] не empty и SameValue(p.[[Key]], key) является true (истинно), то
    i. Установите p.[[Key]] на empty.
    ii. Установите p.[[Value]] на empty.
    iii. Верните true.
6. Вернуть false.
Примечание

Значение empty используется как устройство спецификации, чтобы указать, что запись была удалена. Фактические реализации могут выполнять другие действия, такие как физическое удаление записи из внутренних структур данных.

 

24.3.3.3 WeakMap.prototype.get ( key )

Выполняются следующие шаги:

1. Пусть M будет значением this.
2. Выполнить ? RequireInternalSlot(M, [[WeakMapData]]).
3. Пусть записями entries будет Список M.[[WeakMapData]].
4. Если Тип(key) не является Объектом, вернуть undefined.
5. Для каждой Записи {[[Key]], [[Value]]} p из записей entries выполните
  а. Если p.[[Key]] не empty и SameValue(p.[[Key]], key) является true (истинно), вернуть p.[[Value]].
6. Вернуть undefined.

 

24.3.3.4 WeakMap.prototype.has ( key )

Выполняются следующие шаги:

1. Пусть M будет значением this.
2. Выполнить ? RequireInternalSlot(M, [[WeakMapData]]).
3. Пусть записями entries будет Список M.[[WeakMapData]].
4. Если Тип(key) не является Объектом, вернуть false.
5. Для каждой Записи {[[Key]], [[Value]]} p из записей entries выполните
  а. Если p.[[Key]] не empty и SameValue(p.[[Key]], key) является true (истинно), верните true.
6. Вернуть false.

 

24.3.3.5 WeakMap.prototype.set ( key, value )

Выполняются следующие шаги:

1. Пусть M будет значением this.
2. Выполнить ? RequireInternalSlot(M, [[WeakMapData]]).
3. Пусть записями entries будет Список M.[[WeakMapData]].
4. Если Тип(key) не является Объектом, выбросить исключение TypeError.
5. Для каждой записи {[[Key]], [[Value]]} p записей выполните
  а. Если p.[[Key]] не empty и SameValue(p.[[Key]], key) является true (истинно), то
    i. Установить p.[[Value]] на value.
    ii. Вернуть M.
6. Пусть p будет Записью {[[Key]]: key, [[Value]]: value}.
7. Добавьте p в качестве последнего элемента записей entries.
8. Верните M.

 

24.3.3.6 WeakMap.prototype [ @@toStringTag ]

Начальным значением свойства @@toStringTag является строковое значение «WeakMap».

Это свойство имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}.

 

24.3.4 Свойства экземпляров Слабой Карты (Properties of WeakMap Instances)

Экземпляры Слабой Карты (WeakMap Instances) — это обычные объекты, наследующие свойства от прототипа WeakMap. У экземпляров Слабой Карты (WeakMap Instances) также есть внутренний слот [[WeakMapData]].

 

Информационные ссылки

Стандарт ECMAScript — Раздел «24.3 WeakMap Objects» — https://tc39.es/ecma262/#sec-weakmap-objects