Встроенные объекты, на которые стоит обратить внимание

Как бы я ни любил картографические карты, этот пост в блоге не об этом. Речь идет о встроенной структуре данных в JavaScript.

Что такое карта?

Вы когда-нибудь хотели, чтобы вы могли легко перебирать ключи объекта? Что ж, отличные новости! Карта — это что-то среднее между объектом и массивом. Они по-прежнему представляют собой наборы пар "ключ-значение", но в отличие от обычных объектов ключи карты могут быть любыми значениями (не только строками или символами) и индексируются в порядке вставки. Это означает, что у карт есть полезное свойство size, а также возможность прямой итерации с помощью for…of.

Как они работают?

Конструктор: const myMap = new Map();

Вы можете создать новую карту с любым двумерным массивом ключей и значений, включая другие карты.

const myMapFromArray = new Map([['a', 1], ['b', 2]]);
const myMapClone = new Map(myMap);
const myMapMix = new Map([...myMap, ...myMapFromArray, ['c', 3]]);

Также легко сделать массив из карты.

const myArray = Array.from(myMapMix);
console.log(myMapMix);
    //--> {"a" => 1, "b" => 2, "c" => 3}
console.log(myArray);
    //--> [["a", 1], ["b", 2], ["c", 3]]

И объект.

const myObj = Object.fromEntries(myMap); // or myMap.entries()

Действительно полезным здесь является свойство myMap.size, которое возвращает количество записей в одном выражении. Будьте осторожны, чтобы не использовать myMap.length, потому что он вернет undefined.

myMap.set('key', 'value') создает новую пару ключ-значение, myMap.get('key') возвращает соответствующее значение, а myMap.has('key') возвращает логическое значение, указывающее, содержит ли карта этот ключ. Помните, что ключи на карте могут иметь любое значение.

myMap.delete('key') удаляет пару ключ-значение, а myMap.clear() удаляет все записи на карте.

Как и в обычном объекте, карты имеют myMap.keys(), myMap.values() и myMap.entries(), которые являются парами ключ-значение. Имейте в виду, что возвращаемое значение этих методов является итератором, а не массивом, но вы можете легко использовать Array.from() для создания массива, если хотите.

Использовать итератор над картой очень просто. for (let [k, v] of myMap) { }. Вы также можете использовать этот шаблон с keys(), values() и entries().

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

myMap['d'] = 4;
myMap.get('d');     //--> undefined
myMap.has('d');     //--> false
myMap.delete('d');  //--> false

console.log(myMap['d']);  //--> 4

Каков вариант использования?

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

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

Существует также отдельный объект, называемый WeakMap, где ключи карты должны быть только объектами, что также означает, что ключи не могут быть перечислены. Поскольку на эти ключи слабо ссылаются, они подлежат сборке мусора, если они теряют эту ссылку. Доступны следующие методы: set, get, has и delete.

Также из MDN:

Одним из вариантов использования объектов WeakMap является хранение личных данных для объекта или сокрытие деталей реализации. Следующий пример взят из блога Ника Фитцджеральда Скрытие деталей реализации с помощью ECMAScript 6 WeakMaps. Частные данные и методы принадлежат объекту и хранятся в объекте privates WeakMap. Все, что представлено в экземпляре и прототипе, является общедоступным; все остальное недоступно из внешнего мира, потому что privates не экспортируется из модуля.

ГЛХФ!

TL;DR

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