Полный цикл в digital

Объект WeakMap

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

Создание WeakMap:

// пустой WeakMap
const weakMap1 = new WeakMap();
// WeakMap с инициализацией данными
let key1 = {key:1};
let key2 = {key:2};
let value1 = {name: "Tom"};
let value2 = {name: "Sam"};
const weakMap2 = new WeakMap([[key1, value1], [key2, value2]]);
// или так const weakMap2 = new WeakMap([[{key:1}, {name: "Tom"}], [{key:2}, {name: "Sam"}]]);

Стоит отметить, что объект WeakMap не поддерживает перебор.

Для добавления новых объектов или изменения старых применяется метод set():

let key1 = {key:1};
let key2 = {key:2};
let value1 = {name: "Tom"};
let value2 = {name: "Sam"};
const weakMap2 = new WeakMap([[key1, value1]]);
weakMap2.set(key2, value2);
weakMap2.set(key1, {name: "Kate"});
// {name: "Kate"}
console.log(weakMap2.get(key1));  
// {name: "Sam"}
console.log(weakMap2.get(key2));

Для получения объектов по ключу из WeakMap применяется метод get():

let key1 = {key:1};
let key2 = {key:2};
let value1 = {name: "Tom"};
let value2 = {name: "Sam"};
const weakMap2 = new WeakMap([[key1, value1], [key2, value2]]);
// {name: "Tom"}
console.log(weakMap2.get(key1));

Чтобы проверить наличие элемента по определенному ключу, применяется метод has(), который возвращает true при наличии элемента:

let key1 = {key:1},
key2 = {key:2};
let value1 = {name: "Tom"},
value2 = {name: "Sam"};
const weakMap2 = new WeakMap([[key1, value1]]);
// true
console.log(weakMap2.has(key1));  
// false
console.log(weakMap2.has(key2));

Для удаления элемента по ключу применяется метод delete():

let key1 = {key:1},
key2 = {key:2};
let value1 = {name: "Tom"},
value2 = {name: "Sam"};
const weakMap2 = new WeakMap([[key1, value1], [key2, value2]]);
// true
console.log(weakMap2.has(key1));  
weakMap2.delete(key1);
// false
console.log(weakMap2.has(key1));

Слабые ссылки

Объекты передаются в WeakMap по ссылке. И когда объект перестает существовать в силу различных причин, он удаляется из WeakMap. Рассмотрим следующий пример:

let jsCode = {code: "js"},
tsCode = {code: "ts"};
let js = {lang: "JavaScript"},
ts = {lang: "TypeScript"};
const weakMap = new WeakMap([[jsCode, js], [tsCode, ts]]);
jsCode = null;
// WeakMap {{code: "js"} => {lang: "JavaScript"}, {code: "ts"} => {lang: "TypeScript"}}
console.log(weakMap);  
console.log("Некоторая работа");
const timerId = setTimeout(function(){
// WeakMap {{code: "ts"} => {lang: "TypeScript"}}
console.log(weakMap);  
clearTimeout(timerId);
}, 10000);

В данном случае сначала объект WeakMap хранит ссылки на два элемента с ключами jsCode и tsCode. Далее для переменной jsCode устанавливается значение null:

jsCode = null;

Это приведет к тому, что спустя некоторое время начальное значение этой переменной будет удалено сборщиком мусора JavaScript. Причем если сразу после этого мы посмотрим на содержимое weakMap, то увидим, что объект с ключом jsCode в нем еще присутствует. Однако спустя некоторое время ссылка будет удалена из weakSet. Для эмуляции прошествия времени здесь используется функция setTimeout, которая выводит на консоль содержимое weakSet через 10000 секунд (конкретный период времени, через который сборщик мусора удалит значение, может отличаться).

Теперь сравним с тем, что произойдет, если вместо WeakMap использовать Map:

let jsCode = {code: "js"},
tsCode = {code: "ts"};
let js = {lang: "JavaScript"},
ts = {lang: "TypeScript"};
const map = new Map([[jsCode, js], [tsCode, ts]]);
jsCode = null;
// Map(2) {{code: "js"} => {lang: "JavaScript"}, {code: "ts"} => {lang: "TypeScript"}}
console.log(map);  
console.log("Некоторая работа");
const timerId = setTimeout(function(){
// Map(2) {{code: "js"} => {lang: "JavaScript"}, {code: "ts"} => {lang: "TypeScript"}}
console.log(map);  
clearTimeout(timerId);
}, 10000);

В случае с Map даже спустя некоторое время мы увидим, что в объекте Map до сих пор присутствует объект, для которого было установлено значение null.

Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг