- Операторы
- Управляющие инструкции
- JS Объекты
- Array
- Boolean
- Date
- Error
- Function
- Global
- JSON
- Math
- Number
- Object
- RegExp
- String
- Symbol
- Итераторы и генераторы
- Map и WeakMap
- Set и WeakSet
- Локализация
- браузер BOM
- HTML DOM
- События
- HTML Объекты
- Промисы, async/await
- Сетевые запросы
- Бинарные данные и файлы
- Разное
Set и WeakSet
Set
Объект Set – это особый вид коллекции: «множество» значений (без ключей), где каждое значение может появляться только один раз.
Методы и свойства
let set = new Set( [iterable] )
Метод set() создает новый Set-объект
Параметр
- iterable
- Необязательный. Массив или другой итерируемый объект. Например:
let mySet = new Set( [1,5,"Текст", {a: 1, b: 2}] );
set.size
Свойство size возвращает текущее количество элементов.
let set = new Set(['один', 'два', 'три', 4]); alert ( set.size );
set.add( value )
Метод add() добавляет значение (если оно уже есть, то ничего не делает), возвращает тот же объект
set
.Основная «изюминка» – это то, что при повторных вызовах set.add() с одним и тем же значением ничего не происходит, за счёт этого как раз и получается, что каждое значение появляется один раз.
let set = new Set(); set.add(1).add(5).add("Текст").add(5).add(1).add( {a: 1, b: 2} ); let s=''; for (let v of set) { s += v+'\n'; } alert( s );
Лоторея. Получить 6 чисел из 49:
let loto = new Set(); while (loto.size != 6) { let n = Math.round(Math.random()*48) + 1; // случайное число от 1 до 49 loto.add( n ); } let a = Array.from(loto,x => (x<10?'0':'') + x).sort(); let s=''; for (let k of a) { s += k + ' '; } alert(s);
set.has( value )
Метод has() возвращает
true
, если значениеvalue
присутствует в коллекции, иначеfalse
.let set = new Set([ 1, 2, 3, 4, 5 ]); alert( set.has(1) + ', ' + set.has(3) + ', ' + set.has(77) );
set.delete( value )
Метод delete() удаляет уникальный элемент
value
и возвращаетtrue
, если элемент в объектеSet
существовал и был удален, илиfalse
, если элемент не существует.let o = new Set( ["foo", "bar"] ); alert ( ` ${ o.delete("bar") }, ${ o.delete("bad") }` ); // Удалить Object из Set. let set = new Set(); set.add({ x: 10, y: 20 }).add({ x: 20, y: 30 }); // Delete any point with `x > 10`. set.forEach((point) => { if (point.x > 10) { set.delete(point); } }); alert (set.size);
set.clear()
Метод clear() очищает коллекцию от всех элементов и возвращает
undefined
.let set = new Set( [1,5,"Текст", {a: 1, b: 2}] ); let s = set.size; s += `\n${ set.clear() } \n ${ set.size } \n ${ set.has(1) }`; alert( s );
set.values()
Метод values() возвращает новый
Итератор
, который содержит значения для каждого элемента в объектеSet
в порядке их добавления.Метод keys() является синонимом этого метода (для схожести с объектами
Map
). Он ведёт себя точно так же и возвращает значения элементовSet
.const set = new Set(); set.add(42); set.add('forty two'); const iterator = set.values(); alert( ` ${ iterator.next().value }, ${ iterator.next().value } ` );
set.keys()
Метод keys() является синонимом этого метода (для схожести с объектами
Map
). Он ведёт себя точно так же и возвращает значения элементовSet
.const set = new Set(); set.add(42); set.add('forty two'); const iterator = set.keys(); alert( ` ${ iterator.next().value }, ${ iterator.next().value } ` );
set.entries()
Метод entries() возвращает новый
Итератор
, который содержит массив [значение, значение] для каждого элемента в объекте Set в порядке их добавления. Для объекта Set не существует ключа key, как в объекте Map. Тем не менее, чтобы API было схож с объектом Map, каждая запись содержит значение как в ключе, так и в значении, возвращая массив [значение, значение].const set = new Set(); set.add(42); set.add('forty two'); const iterator = set.entries(); let s = ''; for (const entry of iterator) { s += '\n'+entry; } alert (s);
set[Symbol.iterator]
Метод set[Symbol.iterator] возвращает функцию Set-Iterator, которая является values() по умолчанию.
let set = new Set( [1, "Текст", {a: 1, b: 2}] ); var Iter = set[Symbol.iterator](); // тоже, что set.values() let s = ` ${ Iter.next().value } ${ Iter.next().value } ${ Iter.next().value } \n`; for (let k of set) { // то же самое, что и set.values() s += k+'\n'; } alert (s);
set.forEach(callbackFn[, thisArg])
Метод forEach() выполняет функцию по одному разу для каждого элемента из Set в порядке их расположения. Если указан параметр
thisArg
, он будет использоваться в качествеthis
значения для каждого обратного вызова. Метод возвращаетundefined
Метод forEach() выполняет
callback
по одному разу для каждого значения, которое находится в объекте Set. Функция не будет выполняться для значений, которые были удалены. Тем не менее функция выполнится с элементами, значение которыхundefined
.callback
вызывается с тремя аргументами:1. значение элемента
2. ключ элемента
3. Set-объект обходаВ объектах типа Set нет ключей, поэтому оба первых аргумента принимают значение содержащееся в Set. Это делает метод forEach() для объекта Set совместимым с методами forEach() других объектов, таких как Map и Array.
let s = ''; function SetElements(value1, value2, set) { s += 's[' + value1 + '] = ' + value2 + '\n'; } new Set(['foo', 'bar', undefined]).forEach(SetElements); alert (s);
WeakSet
Объект WeakSet - коллекция, элементами которой могут быть только объекты. Ссылки на эти объекты в WeakSet являются слабыми. Каждый объект может быть добавлен в WeakSet только один раз.
Синтаксис
weakSet = new WeakSet([iterable])
Параметры
- iterable
- Необязательный. При передаче итерируемого объекта, все его элементы будут добавлены в новый WeakSet.
Null
обрабатывается какundefined
.
Объекты WeakSet представляют собой коллекции объектов. Каждый объект в WeakSet встречается только один раз, что обеспечивает его уникальность в рамках коллекции WeakSet.
Главным отличия от объекта Set:
- WeakSet содержит только объекты, тогда как Set - значения любого типа.
- Ссылки на объекты в WeakSet являются слабыми: если на объект, хранимый в WeakSet нет ни одной внешней ссылки, то сборщик мусора удалит этот объект. Также это означает, что WeakSet не итерируем, так как нет возможности получить список текущих хранимых в WeakSet-объектов.
- WeakSet поддерживает только три метода: add, has и delete.
Будучи «слабой» версией оригинальной структуры данных, она тоже служит в качестве дополнительного хранилища. Но не для произвольных данных, а скорее для значений типа «да/нет». Присутствие во множестве WeakSet может что-то сказать нам об объекте.
Например, мы можем добавлять пользователей в WeakSet для учёта тех, кто посещал сайт:
let visitedSet = new WeakSet(); let john = { name: "John" }; let pete = { name: "Pete" }; let mary = { name: "Mary" }; visitedSet.add(john); // John заходил к нам visitedSet.add(pete); // потом Pete visitedSet.add(john); // John снова // visitedSet сейчас содержит двух пользователей // проверим, заходил ли John? alert(visitedSet.has(john)); // true // проверим, заходила ли Mary? alert(visitedSet.has(mary)); // false john = null; // структура данных visitedSet будет очищена автоматически
Наиболее значительным ограничением WeakMap и WeakSet является то, что их нельзя перебрать или взять всё содержимое. Это может доставлять неудобства, но не мешает WeakMap/WeakSet выполнять их главную задачу – быть дополнительным хранилищем данных для объектов, управляемых из каких-то других мест в коде.