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

Объект WeakSet

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

Для создания объекта WeakSet используется его конструктор, в который можно передать начальные значения:

// пустой WeakSet
const weakSet1 = new WeakSet();
// инициализация начальными значениями
const weakSet2 = new WeakSet([{name:"Tom", age: 37}, {name:"Alice", age: 34}]);

Для инициализации как в случае с объектом Set в конструктор передается массив, но данный массив содержит именно объекты, а не скалярные значения, типа чисел или строк.

Для добавления данных в WeakSet применяется метод add():

const weakSet = new WeakSet();
weakSet.add({lang: "JavaScript"});
weakSet.add({lang: "TypeScript"});
// так нельзя - 34 - число, а не объект
// weakSet.add(34);  
// {{lang: "JavaScript"}, {lang: "TypeScript"}}
console.log(weakSet);

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

Для удаления применяется метод delete(), в который передается ссылка на удаляемый объект:

const weakSet = new WeakSet();
const js = {lang: "JavaScript"};
const ts = {lang: "TypeScript"};
weakSet.add(js);
weakSet.add(ts);
weakSet.delete(js);
// {{lang: "TypeScript"}}
console.log(weakSet);

Если надо проверить, имеется ли объект в WeakSet, то можно использовать метод has(), который возвращает true при наличии объекта:

const js = {lang: "JavaScript"};
const ts = {lang: "TypeScript"};
const java = {lang: "Java"};
const weakSet = new WeakSet([js, ts]);
// true
console.log(weakSet.has(ts));  
// false
console.log(weakSet.has(java));

Перебор WeakSet

WeakSet не поддерживает перебор ни с помощью метода ForEach, которого у WeakSet нет, ни с помощью цикла for. Если мы попробуем перебрать WeakSet через цикл for..of:

const weakSet = new WeakSet([
{lang: "JavaScript"}, 
{lang: "TypeScript"}, 
{lang: "Java"}
]);
for(item in weakSet){
console.log(item);
}

мы получим ошибку:

Uncaught TypeError: weakSet is not iterable

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

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

let js = {lang: "JavaScript"};
let ts = {lang: "TypeScript"};
const weakSet = new WeakSet([js, ts]);
js = null;
// {{lang: "JavaScript"}, {lang: "TypeScript"}}
console.log(weakSet);   
console.log("Некоторая работа");
const timerId = setTimeout(function(){
// {{lang: "TypeScript"}}
console.log(weakSet);   
clearTimeout(timerId);
}, 9000);

В данном случае сначала объект WeakSet хранит ссылки на два объекта: js и ts. Далее мы устанавливаем значение для переменной js в null.

Это приведет к тому, что спустя некоторое время начальное значение этой переменной будет удалено сборщиком мусора JavaScript.

js = null;

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

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

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

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

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