Map

Объект 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

var myMap = new Map();

var 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 !== {}
myMap.get(function() {}) // undefined, потому что keyFunc !== function () {}

Использование NaN в качестве ключей Map

NaN может быть использован в качестве ключа. Несмотря на то, что NaN не равен самому себе (NaN !== NaN вернёт true), следующий пример работает, потому что NaN обрабатывается особым образом:

var myMap = new Map();
myMap.set(NaN, "not a number");

myMap.get(NaN); // "not a number"

var otherNaN = Number("foo");
myMap.get(otherNaN); // "not a number"

Итерация Map при помощи for..of

Map может быть итерирован с помощью for..of:

var 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

var kvArray = [["key1", "value1"], ["key2", "value2"]];

// Используйте конструктор Map для преобразования двумерных массивов в Map
var 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 могут быть клонированы:

var original = new Map([
  [1, 'one']
]);

var clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false.

Следует помнить, что данные не клонируются.

Map могут быть слиты, с сохранением уникальности ключей:

var first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

var second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);

// Слияние двух Map. Взят будет последний повторившийся ключ.
// Оператор Spread по сути преобразует Map в массив
var merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

Map могут быть слиты и с Массивами:

var first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

var second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);

// Слияние Map и массива. Как и при слиянии двух Map - взят будет последний повторившийся ключ.
var 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 Latest Draft (ECMA-262)
Определение 'Map' в этой спецификации.
Черновик

Совместимость с браузерами

Update compatibility data on GitHub
КомпьютерыМобильныеServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome для AndroidFirefox для AndroidOpera для AndroidSafari on iOSSamsung InternetNode.js
MapChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 13IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 14Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
Полная поддержка 0.12
Полная поддержка 0.10
Отключено
Отключено From version 0.10: this feature is behind the --harmony runtime flag.
clearChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 19IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 19Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
deleteChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 13IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 14Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
Полная поддержка 0.12
Полная поддержка 0.10
Отключено
Отключено From version 0.10: this feature is behind the --harmony runtime flag.
entriesChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 20IE Нет поддержки НетOpera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 20Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
forEachChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 25IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 25Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
getChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 13IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 14Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка Да
hasChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 13IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 14Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка Да
Key equality for -0 and 0Chrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 29IE Нет поддержки НетOpera Полная поддержка 25Safari Полная поддержка 9WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 29Opera Android Полная поддержка 25Safari iOS Полная поддержка 9Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 4.0.0
keysChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 20IE Нет поддержки НетOpera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 20Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
new Map(iterable)Chrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 13IE Нет поддержки НетOpera Полная поддержка 25Safari Полная поддержка 9WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 14Opera Android Полная поддержка 25Safari iOS Полная поддержка 9Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
new Map(null)Chrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 37IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 9WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 37Opera Android Полная поддержка 25Safari iOS Полная поддержка 9Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
Полная поддержка 0.12
Полная поддержка 0.10
Отключено
Отключено From version 0.10: this feature is behind the --harmony runtime flag.
Map() without new throwsChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 42IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 9WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 42Opera Android Полная поддержка 25Safari iOS Полная поддержка 9Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
prototypeChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 13IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 14Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка Да
setChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 13IE Частичная поддержка 11
Замечания
Частичная поддержка 11
Замечания
Замечания Returns 'undefined' instead of the 'Map' object.
Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 14Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка Да
sizeChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 19
Замечания
Полная поддержка 19
Замечания
Замечания From Firefox 13 to Firefox 18, the size property was implemented as a Map.prototype.size() method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification.
IE Полная поддержка 11Opera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 19
Замечания
Полная поддержка 19
Замечания
Замечания From Firefox 13 to Firefox 18, the size property was implemented as a Map.prototype.size() method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification.
Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
valuesChrome Полная поддержка 38Edge Полная поддержка 12Firefox Полная поддержка 20IE Нет поддержки НетOpera Полная поддержка 25Safari Полная поддержка 8WebView Android Полная поддержка 38Chrome Android Полная поддержка 38Firefox Android Полная поддержка 20Opera Android Полная поддержка 25Safari iOS Полная поддержка 8Samsung Internet Android Полная поддержка 3.0nodejs Полная поддержка 0.12
@@iteratorChrome Полная поддержка 43Edge Полная поддержка 12Firefox Полная поддержка 36
Полная поддержка 36
Нет поддержки 27 — 36
Замечания Альтернативное имя
Замечания A placeholder property named @@iterator is used.
Альтернативное имя Использует нестандартное имя: @@iterator
Нет поддержки 17 — 27
Замечания Альтернативное имя
Замечания A placeholder property named iterator is used.
Альтернативное имя Использует нестандартное имя: iterator
IE Нет поддержки НетOpera Полная поддержка 30Safari Полная поддержка ДаWebView Android Полная поддержка 43Chrome Android Полная поддержка 43Firefox Android Полная поддержка 36
Полная поддержка 36
Нет поддержки 27 — 36
Замечания Альтернативное имя
Замечания A placeholder property named @@iterator is used.
Альтернативное имя Использует нестандартное имя: @@iterator
Нет поддержки 17 — 27
Замечания Альтернативное имя
Замечания A placeholder property named iterator is used.
Альтернативное имя Использует нестандартное имя: iterator
Opera Android Полная поддержка 30Safari iOS Полная поддержка ДаSamsung Internet Android Полная поддержка 4.0nodejs Полная поддержка 0.12
@@speciesChrome Полная поддержка 51Edge Полная поддержка 13Firefox Полная поддержка 41IE Нет поддержки НетOpera Полная поддержка 38Safari Полная поддержка 10WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android Полная поддержка 41Opera Android Полная поддержка 41Safari iOS Полная поддержка 10Samsung Internet Android Полная поддержка 5.0nodejs Полная поддержка 6.5.0
Полная поддержка 6.5.0
Полная поддержка 6.0.0
Отключено
Отключено From version 6.0.0: this feature is behind the --harmony runtime flag.
@@toStringTagChrome Полная поддержка 44Edge Нет поддержки НетFirefox Полная поддержка 51IE Нет поддержки НетOpera Нет поддержки НетSafari Нет поддержки НетWebView Android Полная поддержка 44Chrome Android Полная поддержка 44Firefox Android Полная поддержка 51Opera Android Нет поддержки НетSafari iOS Нет поддержки НетSamsung Internet Android Полная поддержка 4.0nodejs Нет поддержки Нет

Легенда

Полная поддержка  
Полная поддержка
Частичная поддержка  
Частичная поддержка
Нет поддержки  
Нет поддержки
Смотрите замечания реализации.
Смотрите замечания реализации.
Пользователь должен сам включить эту возможность.
Пользователь должен сам включить эту возможность.
Использует нестандартное имя.
Использует нестандартное имя.

Смотрите также