Объект Map
содержит пары ключ-значение и сохраняет порядок вставки. Любое значение (как объекты, так и примитивы) могут быть использованы в качестве ключей.
Синтаксис
new Map([iterable])
Параметры
iterable
- Массив или любой другой итерируемый объект чьими элементами являются пары ключ-значение (массивы из двух элементов, например
[[ 1, 'one' ],[ 2, 'two' ]]
). Все пары ключ-значение будут добавлены в новый экземплярMap
;null
расценивается какundefined
.
Описание
Объект Map
итерируется в порядке вставки его элементов — цикл for...of
будет возвращать массив [key, value]
на каждой итерации.
Key equality
Сравнение ключей основано на алгоритме "SameValueZero": NaN
равно NaN
(несмотря на то, что NaN !== NaN
), все другие значения рассматриваются равными исходя из семантики оператора строгого равенства ===
. В текущей спецификации ECMAScript -0
и +0
принимаются равными, но в ранних версиях обсуждения это было не так (см. "Value equality for -0 and 0" в таблице совместимости с браузерами).
Сравнение Объектов и Map
Объекты похожи на Map
в том, что оба позволяют устанавливать значения по ключам, получать эти значения, удалять ключи и проверять их наличие. В связи с этим (и потому, что не было встроенных альтернатив), Объекты
исторически использовались как Map
. Однако, у них есть ряд отличий, который дает преимущества Map
в ряде случаев:
- Ключами
Объекта
выступаютСтроки
иСимволы
, в то время как любое значение может быть ключомMap
, включаяфункции
,объекты
и примитивы. - В отличие от
Объектов
, ключи вMap
упорядочены. Таким образом, во время итерацииMap
, ключи возвращаются в порядке вставки. - Вы легко можете получить количество элементов в
Map
с помощью свойстваsize
, в то время как количество элементовОбъекта
может быть определено только вручную. Map
- итерируемый объект и может быть итерирован напрямую, в то время какОбъект
требует ручного получения списка ключей и их итерации.Объект
имеет прототип и поэтому имеет стандартный набор ключей, который, при неосторожности, может пересекаться с вашими ключами. С момента выхода ES5 это может быть изменено с помощьюmap = Object.create(null)
.Map
может иметь более высокую производительность в случаях частого добавления или удаления ключей.
Свойства
Map.length
- Значение свойства
length
всегда равно 0. - Чтобы узнать количество элементов в
Map
- используйтеMap.prototype.size
. get Map[@@species]
- Функция-конструктор которая используется для создания производных объектов.
Map.prototype
- Представляет прототип конструктора
Map
. Позволяет добавлять свойства всем объектам типаMap
.
Экземпляры Map
Все экземпляры Map
наследуются от Map.prototype
.
Свойства
Map.prototype.constructor
- Возвращает функцию, которая создала прототип экземпляра. Это функция
Map
по умолчанию. Map.prototype.size
- Возвращает количество пар ключ/значение в объекте
Map
.
Методы
Map.prototype.clear()
- Удаляет все пары ключ / значение из объекта
Map
. Map.prototype.delete(key)
- Возвращает
true
, если элемент в объектеMap
существовал и был удален, или false, если элемент не существует.Map.prototype.has(key)
вернетfalse
позже. Map.prototype.entries()
- Возвращает новый объект
Iterator
который содержит массив[key, value]
для каждого элемента в объектеMap
в порядке вставки. Map.prototype.forEach(callbackFn[, thisArg])
- Вызывает callbackFn один раз для каждой пары ключ-значение, присутствующей в объекте
Map
, в порядке вставки. Если для thisArg предоставляется параметр для forEach, он будет использоваться как значение this для каждого обратного вызова. Map.prototype.get(key)
- Возвращает значение связанное с
key
, илиundefined
если его нет. Map.prototype.has(key)
- Возвращает логическое значение, подтверждающее, было ли значение связано с
key
в объектеMap
или нет. Map.prototype.keys()
- Возвращает новый объект
Iterator
содержащий ключи для каждого элемента в объектеMap
в порядке вставки. Map.prototype.set(key, value)
- Устанавливает значение для
key
в объектеMap
. Возвращает объектMap
. Map.prototype.values()
- Возвращает новый объект
Iterator
который содержит значения для каждого элемента в объектеMap
в порядке вставки. Map.prototype[@@iterator]()
- Возвращает новый объект
Iterator
который содержит массив[key, value]
для каждого элемента в объектеMap
в порядке вставки.
Примеры
Использование объекта Map
const myMap = new Map();
const keyObj = {},
keyFunc = function () {},
keyString = 'a string';
// задание значений
myMap.set(keyString, 'value associated with “a string”');
myMap.set(keyObj, 'value associated with keyObj');
myMap.set(keyFunc, 'value associated with keyFunc');
myMap.size; // 3
// получение значений
myMap.get(keyString); // value associated with “a string”
myMap.get(keyObj); // value associated with keyObj
myMap.get(keyFunc); // value associated with keyFunc
myMap.get('a string'); // "value associated with 'a string'"
// потому что keyString === 'a string'
myMap.get({}); // undefined, потому что keyObj !== {} ({} — это литеральная нотация конструктора класса Object)
myMap.get(function() {}) // undefined, потому что keyFunc !== function () {}
Использование NaN в качестве ключей Map
NaN
может быть использован в качестве ключа. Несмотря на то, что NaN
не равен самому себе (NaN !== NaN
вернёт true), следующий пример работает, потому что NaN
обрабатывается особым образом:
const myMap = new Map();
myMap.set(NaN, 'not a number');
myMap.get(NaN); // not a number
const otherNaN = Number('foo');
myMap.get(otherNaN); // not a number
Итерация Map при помощи for..of
Map
может быть итерирован с помощью for..of
:
const myMap = new Map();
myMap.set(0, 'zero');
myMap.set(1, 'one');
for (var [key, value] of myMap) {
console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one
for (var key of myMap.keys()) {
console.log(key);
}
// 0
// 1
for (var value of myMap.values()) {
console.log(value);
}
// zero
// one
for (var [key, value] of myMap.entries()) {
console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one
Итерация Map при помощи forEach()
Map
может быть итерирован с помощью метода forEach()
:
myMap.forEach(function(value, key) {
console.log(`${key} => ${value}`);
});
// 0 => zero
// 1 => one
Взаимоотношения с объектом Array
const kvArray = [['key1', 'value1'], ['key2', 'value2']];
// Используйте конструктор Map для преобразования двумерных массивов в Map
const myMap = new Map(kvArray);
myMap.get('key1'); // вернёт “value1”
// Используйте функцию Array.from для трансформации Map в двумерный key-value массив
console.log(Array.from(myMap)); // Выведет точно такой же массив как kvArray
// Или используйте итераторы keys или values чтобы преобразовать ключи или значения в массивы
console.log(Array.from(myMap.keys())); // Выведет ['key1', 'key2']
Клонирование и сляние Map
Равно как и Массивы
, Map
могут быть клонированы:
const original = new Map([
[1, 'one']
]);
const clone = new Map(original);
console.log(clone.get(1)); // one
console.log(original === clone); // false.
Следует помнить, что данные не клонируются.
Map
могут быть слиты, с сохранением уникальности ключей:
const first = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
const second = new Map([
[1, 'uno'],
[2, 'dos']
]);
// Слияние двух Map. Взят будет последний повторившийся ключ.
// Оператор Spread по сути преобразует Map в массив
const merged = new Map([...first, ...second]);
console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
Map могут быть слиты и с Массивами
:
const first = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
const second = new Map([
[1, 'uno'],
[2, 'dos']
]);
// Слияние Map и массива. Как и при слиянии двух Map - взят будет последний повторившийся ключ.
const merged = new Map([...first, ...second, [1, 'eins']]);
console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
Спецификации
Спецификация | Статус | Комментарий |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Определение 'Map' в этой спецификации. |
Стандарт | Initial definition. |
ECMAScript (ECMA-262) Определение 'Map' в этой спецификации. |
Живой стандарт |
Совместимость с браузерами
BCD tables only load in the browser