WeakMap

Эта статья нуждается в техническом обзоре. Как вы можете помочь.

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

Сводка

Объект WeakMap — коллекция пар ключ-значение. В качестве ключей могут быть использованы только объекты, а значения могут быть произвольных типов.

Синтаксис

new WeakMap([iterable])

Параметры

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

Описание

Ключами WeakMap могут быть только объекты. Примитивы в качестве ключей не допускаются (т.е. Symbol не может быть ключом WeakMap).

Почему WeakMap?

Опытный JavaScript разработчик заметит, что это API можно реализовать на JavaScript c помощью двух массивов (один для ключей, второй для значений) и четырех общих API методов. У такой реализации было бы два главных неудобства. Первым является O(n) поиск (где n — количество ключей в словаре). Вторым – проблема утечки памяти. В словарях, написанных вручную, массив с ключами будет хранить ссылки на объекты-ключи, не давая им быть помеченными сборщиком мусора. В нативных WeakMap, ссылки на объекты-ключи хранятся "слабо", что означает то, что они не предотвратят сборку мусора в том случае, если других ссылок на объект не будет.

Из-за того, что ссылки являются слабыми, ключи WeakMap не перечисляемы (то есть нет метода, который возвращает список ключей). Иначе список бы зависел от состояния сбора мусора, представляя индетерминизм. Если Вы хотите иметь список ключей, Вам следует поддерживать его самостоятельно.

Свойства

WeakMap.length
Значение свойства length всегда равно 0.
WeakMap.prototype
Представляет прототип конструктора WeakMap. Позволяет добавлять свойства всем объектам типа WeakMap.

Экземпляры WeakMap

Все экземпляры WeakMap унаследованы от WeakMap.prototype.

Свойства

WeakMap.prototype.constructor
Returns the function that created an instance's prototype. This is the WeakMap function by default.

Методы

WeakMap.prototype.delete(key)
Removes any value associated to the key. WeakMap.prototype.has(key) will return false afterwards.
WeakMap.prototype.get(key)
Returns the value associated to the key, or undefined if there is none.
WeakMap.prototype.has(key)
Returns a Boolean asserting whether a value has been associated to the key in the WeakMap object or not.
WeakMap.prototype.set(key, value)
Sets the value for the key in the WeakMap object. Returns the WeakMap object.
WeakMap.prototype.clear()
Removes all key/value pairs from the WeakMap object. Note that it is possible to implement a WeakMap-like object that has a .clear() method by encapsulating a WeakMap object that hasn't it (see example on page WeakMap)

Примеры

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

var wm1 = new WeakMap(),
    wm2 = new WeakMap(),
    wm3 = new WeakMap();
var o1 = {},
    o2 = function(){},
    o3 = window,
    o4 = [1, 2, 3];

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // значением может быть что угодно, включая объект или функцию
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // ключами и значениями могут быть объекты. Даже WeakMap-ами

wm1.get(o2); // "azerty"
wm2.get(o2); // undefined, потому что нет значения для o2 в wm2
wm2.get(o3); // undefined, потому что это установленное значение

wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (даже если значение равно 'undefined')

wm3.set(o1, 37);
wm3.get(o1); // 37

wm1.has(o1);   // true
wm1.delete(o1);
wm1.has(o1);   // false

 

Пример: Реализация класса WeakMap с помощью метода .clear()

Для демонстрации, следующий пример использует новую конструкцию из ECMAScript 2015 class, которая на данный момент реализована далеко не везде.

class ClearableWeakMap {
    constructor(init) {
        this._wm = new WeakMap(init)
    }
    clear() {
        this._wm = new WeakMap
    }
    delete(k) {
        return this._wm.delete(k)
    }
    get(k) {
        return this._wm.get(k)
    }
    has(k) {
        return this._wm.has(k)
    }
    set(k, v) {
        this._wm.set(k, v)
        return this
    }
}

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

Спецификация Статус Комментарий
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'WeakMap' в этой спецификации.
Стандарт Изначальное определение.

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

Feature Chrome Firefox (SpiderMonkey) Internet Explorer Opera Safari
Basic support 36 6.0 (6.0) 11 23 7.1
new WeakMap(iterable) 38 36 (36) Нет 25 Нет
clear() 36 20.0 (20.0) 11 23 7.1
Constructor argument: new WeakMap(null) (Да) 37 (37) ? ? ?
Monkey-patched set() in Constructor (Да) 37 (37) ? ? ?
Feature Android Firefox Mobile (SpiderMonkey) IE Mobile Opera Mobile Safari Mobile
Basic support 35 6.0 (6.0) Нет Нет iOS 8
new WeakMap(iterable) 38 36.0 (36) Нет Нет Нет
clear() 35 20.0 (20.0) Нет Нет iOS 8
Constructor argument: new WeakMap(null) ? (Да) 37.0 (37) ? ? ?
Monkey-patched set() in Constructor ? (Да) 37.0 (37) ? ? ?

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: icw82, zamuka, RumyantsevMichael, casfcitizen, restrry, shvaikalesh, hellboy81
 Обновлялась последний раз: icw82,