This article is in need of an editorial review.
Это экспериментальная технология, часть предложения Harmony (ECMAScript 6).
Поскольку спецификация этой технологии ещё не стабилизировалась, проверьте таблицу совместимости её использования в различных браузерах. Также обратите внимание, что синтаксис и поведение экспериментальной технологии могут быть изменены в будущих версиях браузеров в соответствии с изменениями в спецификации.
Сводка
Объект Map является простым ассоциативным массивом. Любые типы (как объекты, так и примитивы) могут быть использованы в качестве ключа или значения.
Синтаксис
new Map([iterable])
Параметры
-
iterable - Может быть массивом или любым другим итерируемым объектом, элементы которого являются парами ключ-значение. Каждая пара ключ-значение будет добавлена во вновь созданный экземпляр Map.
Описание
Элементы объекта Map можно обойти в порядке их вставки при помощи цикла for..of, где на каждой итерации будет возвращаться массив [ключ, значение].
Сравнение ключей
Сравнение ключей основано на алгоритме "подобное значение": NaN равно NaN (несмотря на то, что NaN !== NaN); все другие значения рассматриваются равными исходя из семантики оператора строго равенства ===. В ранних версиях черновика ECMAScript 6 -0 и +0 считались разными (несмотря на то, что -0 === +0), это было изменено в последующих версиях и адаптировано в Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26) (ошибка 952870) и последней ночной сборке Chrome.
Сходство объектов и map
Объекты похожи на Map в том, что и те и другие позволяют задавать значения по ключам, получать эти значения, удалять ключи и проверять наличие ключа. В связи с этим, исторически объекты использовались как Map, однако, у них есть существенные отличия:
Объектимеет прототип, что означает наличие стандартных значений в ассоциативном массиве. Однако, это можно обойти при помощи выраженияmap = Object.create(null).- В
объектеключи должны бытьстроками, когда вMapони могут иметь любой тип. - Вы можете легко получить размер
Map, в то время как вобъектенеобходимо самостоятельно его учитывать.
Используйте ассоциативный массив вместо объекта когда тип ключей не известен до момента исполнения, либо тип всех ключей и тип всех значений одинаковый.
Используйте объекты, когда используется логика взаимодействия с ним как с отдельным элементом.
Свойства
-
Map.length -
Значение свойства
lengthвсегда равно 1. -
Map.prototype -
Представляет прототип конструктора
Map. Позволяет добавлять свойства всем объектам типаMap.
Экземпляры Map
Все экземпляры Map унаследованы от Map.prototype.
Свойства
Map.prototype.constructor- Returns the function that created an instance's prototype. This is the
Mapfunction by default. Map.prototype.size- Returns the number of key/value pairs in the
Mapobject.
Методы
Map.prototype.clear()- Removes all key/value pairs from the
Mapobject. Map.prototype.delete(key)- Removes any value associated to the
keyand returns the value thatMap.prototype.has(value)would have previously returned.Map.prototype.has(key)will returnfalseafterwards. Map.prototype.entries()- Returns a new
Iteratorobject that contains an array of[key, value]for each element in theMapobject in insertion order. Map.prototype.forEach(callbackFn[, thisArg])- Calls callbackFn once for each key-value pair present in the
Mapobject, in insertion order. If a thisArg parameter is provided to forEach, it will be used as the this value for each callback. Map.prototype.get(key)- Returns the value associated to the
key, orundefinedif there is none. Map.prototype.has(key)- Returns a boolean asserting whether a value has been associated to the
keyin theMapobject or not. Map.prototype.keys()- Returns a new
Iteratorobject that contains the keys for each element in theMapobject in insertion order. Map.prototype.set(key, value)- Sets the value for the
keyin theMapobject. Returns theMapobject. Map.prototype.values()- Returns a new
Iteratorobject that contains the values for each element in theMapobject in insertion order. Map.prototype[@@iterator]()- Returns a new
Iteratorobject that contains an array of[key, value]for each element in theMapobject in insertion order.
Примеры
Использование объекта 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
Ассоциативные массивы можно обойти при помощи цикла a for..of:
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
alert(key + " = " + value);
}
// Отобразит 2 предупреждения; первое "0 = zero" и второе "1 = one"
for (var key of myMap.keys()) {
alert(key);
}
// Отобразит 2 предупреждения; первое "0" и второе "1"
for (var value of myMap.values()) {
alert(value);
}
// Отобразит 2 предупреждения; первое "zero" и второе "one"
for (var [key, value] of myMap.entries()) {
alert(key + " = " + value);
}
// Отобразит 2 предупреждения; первое "0 = zero" и второе "1 = one"
myMap.forEach(function(value, key, myMap) {
alert(key + " = " + value);
})
// Отобразит 2 предупреждения; первое "0 = zero" и второе "1 = one"
Взаимоотношения с объектом Array
var kvArray = [["key1", "value1"], ["key2", "value2"]];
// Используйте конструктор Map для преобразования двумерных массивов в ассоциативные
var myMap = new Map(kvArray);
myMap.get("key1"); // вернёт "value1"
// Используйте переменный оператор для преобразования ассоциативного в двумерный массив
alert(uneval([...myMap])); // Отобразит тот же массив, что и kvArray
// Или используйте переменный оператор для ключей или значений итератора для получения
// массива только ключей или значений
alert(uneval([...myMap.keys()])); // Отобразит ["key1", "key2"]
Спецификации
| Спецификация | Статус | Комментарий |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) Определение 'Map' в этой спецификации. |
Стандарт | Изначальное определение. |
Совместимость с браузерами
| Возможность | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Базовая поддержка |
31 [1] |
13 (13) | 11 | 25 | 7.1 |
Аргумент конструктора: new Map(iterable) |
38 | 13 (13) | Нет | 25 | Нет |
| Итерируемость | 38 | 17 (17) | Нет | 25 | 7.1 |
Map.clear() |
31 [1] 38 |
19 (19) | 11 | 25 | 7.1 |
Map.keys(), Map.values(), Map.entries() |
37 [1] 38 |
20 (20) | Нет | 25 | 7.1 |
Map.forEach() |
36 [1] 38 |
25 (25) | 11 | 25 | 7.1 |
| Равенство ключей -0 и 0 | 34 [1] 38 |
29 (29) | Нет | 25 | Нет |
| Возможность | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Базовая поддержка | Нет | 31 [1] 38 |
13.0 (13) | Нет | Нет | iOS 8 |
Аргумент конструктора: new Map(iterable) |
Нет | 38 | 13.0 (13) | Нет | Нет | Нет |
| Итерируемость | Нет | Нет | 17.0 (17) | Нет | Нет | iOS 8 |
Map.clear() |
Нет | 31 [1] 38 |
19.0 (19) | Нет | Нет | iOS 8 |
Map.keys(), Map.values(), Map.entries() |
Нет | 37 [1] 38 |
20.0 (20) | Нет | Нет | iOS 8 |
Map.forEach() |
Нет | 36 [1] 38 |
25.0 (25) | Нет | Нет | iOS 8 |
| Равенство ключей -0 и 0 | Нет | 34 [1] 38 |
29.0 (29) | Нет | Нет | Нет |
[1] Функция доступна при настройке. В chrome://flags, активируйте “Enable Experimental JavaScript”.