Map
Map jest prostym obiektem mapującym klucze na wartości. Każdy element (zarówno obiekt jak i wartości proste (en-US)) mogą być użyte zarówno jako klucz jak i wartość.
Składnia
new Map([iterable])
Parametry
iterable- Iterable jest tablicą lub innym iterowalnym obiektem, którego elementy są parami typu klucz-wartość (np. 2 elementowa tablica). Każda para klucz-wartość jest dodawana do obiektu new Map.
nulljest traktowane jakoundefined.
Opis
Obiekt Map iteruje swoje elementy we wprowadzonej kolejności — pętla for...of (en-US) zwraca tablicę [key, value] dla każdej iteracji.
Należy pamiętać, że kolejność iteracji dla Map mapującej obiekty, w szczególności np. dla słownika słowników, odzwieciedlać będzie jedynie kolejność dodawania obiektów do kolekcji, natomiast kolejność dodawania elementów do samych obiektów nie jest gwarantowana i powinna być traktowana jako losowa.
Równość kluczy
Klucze porównywane są według algorytmu "same-value" (tej samej wartości).
NaN jest traktowana jako równa NaN (mimo tego, że NaN !== NaN). Wszystkie inne wartości są uważane za równe zgodnie z semantyką === operatora równości.
W obecnej specyfikacji ECMAScript -0 === +0, choć wcześniejsze propozycje zakładały inne zachowanie, co zaowocowało implementacją w niektórych wersjach przeglądarek. Szczegóły zawarte są w "Value equality for -0 and 0" w tabeli kompatybilności przeglądarek.
Porównanie Obiektów i Map
Obiekty są podobne do Map. W obu przypadkach pozwalają ustawić klucze dla wartości, zwracają te wartości, usuwają klucze i wykrywają czy coś jest przechowywane jako klucz. Z tego powodu (i ponieważ nie było innych wbudowanych alternatyw), Object był używany wcześniej jako Map. Istnieją jednak ważne różnice pomiędzy Obiektami i Mapami, które powodują, że Map jest lepszym wyborem w pewnych przypadkach:
- Klucze obiektu są
Stringami' iSymbolami, podczas gdy dlaMapmogą być dowolną wartością, włączając w to funkcje, obiekty czy wartości proste. - Można łatwo pobrać wielkość mapy używając właściwości
size, podczas gdy wielkość obiektu musi być określana ręcznie. - Po mapie można iterować bezpośrednio, iteracja po obiekcie wymaga pobrania jego kluczy i iteracji po ich liście.
- Obiekt posiada prototyp, istnieją więc domyślne klucze, które mogą kolidować z Twoimi kluczami, jeśli nie jesteś ostrożny. Można ominąć ten problem używając
Object.create(null)(dostępne od ES5), ale było to rzadko stosowane rozwiązanie. - Mapa może osiągnąć lepszą wydajność w scenariuszu, w którym często dodajemy i usuwamy pary klucz-wartość.
Nie oznacza to, że powinno się używać Maps wszędzie. Obiekty są wciąż używane w większości przypadków. Instancje Map są użyteczne dla kolekcji, warto rozważyć ich zaadaptowanie jedynie w przypadkach, gdy wcześniej używano dla nich obiektów. Obiekty powinny być używane jako rejestr z polami i metodami. Jeśli wciąż nie jesteś pewien czego użyć, pomocne mogą okazać się poniższe pytania:
- Czy klucze są nieznane do momentu uruchomienia programu? Czy potrzebujesz wyszukiwać lub tworzyć je dynamicznie?
- Czy wszystkie wartości mają ten sam typ? Czy mogą być użyte wymiennie?
- Czy potrzebujesz kluczy, które nie są typu string?
- Czy pary klucz-wartość są często dodawane lub usuwane?
- Czy kolekcja powinna być iterowalna?
Jeśli odpowiedziałeś 'tak' na którekolwiek z tych pytań, prawdopodobnie powinieneś użyć Map. I przeciwnie, jeśli masz zamknięty zbiór kluczy, jeśli musisz odwoływać się do poszczególnych, specyficznych kluczy a każdy z nich ma swoje, odrębne od innych znaczenie, najprawdopodobniej potrzebujesz obiektu.
Własności
Map.length- Wartość
lengthjest zawsze równa 0. get Map[@@species](en-US)- Funkcja konstruktora używana do tworzenia obiektów pochodnych.
Map.prototype(en-US)- Reprezentuje prototyp funkcji konstruktora
Map. Pozwala rozszerzać prototyp wszystkich obiektówMapo własne własności.
Instancje Map
Wszystkie instancje Map dziedziczą po Map.prototype (en-US).
Własności
{{page('en-US/Web/JavaScript/Reference/Global_Objects/Map/prototype','Properties')}}
Metody
{{page('en-US/Web/JavaScript/Reference/Global_Objects/Map/prototype','Methods')}}
Przykłady
Używanie obiektu typu Map
var myMap = new Map();
var keyString = 'a string',
keyObj = {},
keyFunc = function() {};
// setting the values
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
// getting the values
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'"
// because keyString === 'a string'
myMap.get({}); // undefined, because keyObj !== {}
myMap.get(function() {}) // undefined, because keyFunc !== function () {}
Użycie NaN jako kluczy w Map
NaN can also be used as a key. Even though every NaN is not equal to itself (NaN !== NaN is true), the following example works, because NaNs are indistinguishable from each other:
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"
Iteracja po Map przy użyciu 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
Iteracja po Map przy użyciu forEach()
myMap.forEach(function(value, key) {
console.log(key + ' = ' + value);
});
// Will show 2 logs; first with "0 = zero" and second with "1 = one"
Relacja do obiektów typu Array
var kvArray = [['key1', 'value1'], ['key2', 'value2']];
// Use the regular Map constructor to transform a 2D key-value Array into a map
var myMap = new Map(kvArray);
myMap.get('key1'); // returns "value1"
// Use the spread operator to transform a map into a 2D key-value Array.
console.log(uneval([...myMap])); // Will show you exactly the same Array as kvArray
// Or use the spread operator on the keys or values iterator to get
// an array of only the keys or values
console.log(uneval([...myMap.keys()])); // Will show ["key1", "key2"]
Specyfikacje
| Specyfikacja | Status | Komentarz |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Map' in that specification. |
Standard | Początkowa definicja |
| ECMAScript (ECMA-262) The definition of 'Map' in that specification. |
Living Standard |
Kompatybilność przeglądarek
| Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|---|
| Basic support |
38 [1] |
12 | 13 (13) | 11 | 25 | 7.1 |
Constructor argument: new Map(iterable) |
38 | 12 | 13 (13) | No support | 25 | 9 |
| iterable | 38 | 12 | 17 (17) | No support | 25 | 7.1 |
Map.clear() |
31 38 |
12 | 19 (19) | 11 | 25 | 7.1 |
Map.keys(), Map.values(), Map.entries() |
37 38 |
12 | 20 (20) | No support | 25 | 7.1 |
Map.forEach() |
36 38 |
12 | 25 (25) | 11 | 25 | 7.1 |
| Key equality for -0 and 0 | 34 38 |
12 | 29 (29) | No support | 25 | 9 |
Constructor argument: new Map(null) |
(Yes) | 12 | 37 (37) | 11 | (Yes) | 9 |
Monkey-patched set() in Constructor |
(Yes) | 12 | 37 (37) | No support | (Yes) | 9 |
Map[@@species] |
51 | 13 | 41 (41) | No support | 38 | 10 |
Map() without new throws |
(Yes) | 12 | 42 (42) | 11 | (Yes) | 9 |
| Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | No support | 38 [1] | 13.0 (13) | No support | No support | 8 |
Constructor argument: new Map(iterable) |
No support | 38 | 13.0 (13) | No support | No support | 9 |
| iterable | No support | No support | 17.0 (17) | No support | No support | 8 |
Map.clear() |
No support | 31 38 |
19.0 (19) | No support | No support | 8 |
Map.keys(), Map.values(), Map.entries() |
No support | 37 38 |
20.0 (20) | No support | No support | 8 |
Map.forEach() |
No support | 36 38 |
25.0 (25) | No support | No support | 8 |
| Key equality for -0 and 0 | No support | 34 38 |
29.0 (29) | No support | No support | No support |
Constructor argument: new Map(null) |
? | (Yes) | 37.0 (37) | ? | ? | 9 |
Monkey-patched set() in Constructor |
? | (Yes) | 37.0 (37) | ? | ? | 9 |
Map[@@species] |
? | ? | 41.0 (41) | ? | ? | 10 |
Map() without new throws |
5.1 | ? | 42.0 (42) | ? | ? | 9 |
[1] Starting with Chrome 31, the feature was available behind a preference. In chrome://flags, activate the entry “Enable Experimental JavaScript”.