Map オブジェクトは単純なキー/値写像(マップ)です。キーあるいは値として任意の値(オブジェクト、プリミティブ値とも)を使うことができます。

構文

new Map([iterable])

引数

iterable
要素がキー・値の対(2 要素の配列)である Array または他の反復処理可能なオブジェクトです。それぞれのキー・値対が新しい Map に追加されます。

解説

Map オブジェクトはその要素について挿入順で反復処理を行うことができます。for...of ループは各処理で [キー, 値] の配列を返します。

キーの等価性

キーの等価性は「same-value」アルゴリズムに基づきます:NaNNaN と同一(NaN !== NaN にもかかわらず)と見なされ、他のすべての値は === 演算子の動作に従って等しいと見なされます。ECMAScript 6 ドラフトの以前の版では -0+0 は異なる(-0 === +0 にもかかわらず)と見なされていましたが、後の版で変更され、Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26) (バグ 952870) と最近の nightly Chrome で適用されています。

オブジェクトとマップの比較

ObjectsMap は、両者とも値へのキーを設定したり、それらの値を取り出したり、キーを削除したり、また何かがあるキーに格納されているかを判定したりすることができるという点で似ています。このため、歴史的に ObjectMap として使われてきました。しかし、Map の使用を望ましくする ObjectMap 間の重要な違いが存在します。

  • Object はプロトタイプを持つため、既定のキーがマップ中に存在します。しかし、これは map = Object.create(null) を使うことで回避することができます。
  • Object のキーは StringsSymbols ですが、Map では任意の値がキーとなり得ます。
  • Map の大きさは簡単に得ることができます。一方、Object の大きさは手動で保つ必要があります。

これは Map をいつも使えばいいということではありません。オブジェクトはまだ多くの場面で使えます。Map インスタンスはコレクションとして使う場合のみに役に立ちます。以前オブジェクトをこのように使っていたコードに Map を使うことを考えてみるべきです。オブジェクトはメンバ変数とメソッドを備えたレコードとして使われます。もしまだどちらを使えばいいかわからないなら、以下の質問に答えてみてください。

  • キーがいつも実行時までわからない、またはキーを直接調べる必要がありますか?
  • すべての値が同じ型で、交換して使用できますか?
  • 文字列でないキーが必要ですか?
  • キーと値のペアを時々、追加または削除しますか?
  • 簡単に量が変わるキーと値のペアがありますか?
  • そのコレクションをイテレートしますか?

これらはあなたが Map をコレクションとして使いたいときのサインです。もし対照的に、固定された量のキーがあり、それら個々に操作し、Mapの使い方と区別する場合、オブジェクトを使いましょう。

プロパティ

Map.length
length プロパティの値は 0 です。
get Map[@@species]
派生クラスを生成するためのコンストラクタ関数です。
Map.prototype
Map コンストラクタのプロトタイプを表します。すべての Map オブジェクトに追加のプロパティを定義でいます。

Map インスタンス

すべての Map インスタンスは Map.prototype を継承します。

プロパティ

メソッド

Map オブジェクトの使用

var myMap = new Map();

var keyString = "文字列",
    keyObj = {},
    keyFunc = function () {};

// 値を設定する
myMap.set(keyString, "'文字列' と関連付けられた値");
myMap.set(keyObj, "keyObj と関連付けられた値");
myMap.set(keyFunc, "keyFunc と関連付けられた値");

myMap.size; // 3

// 値を取得する
myMap.get(keyString);    // "'文字列' と関連付けられた値"
myMap.get(keyObj);       // "keyObj と関連付けられた値"
myMap.get(keyFunc);      // "keyFunc と関連付けられた値"

myMap.get("文字列");   // "'文字列' と関連付けられた値"
                         // keyString === '文字列' であるため
myMap.get({});           // undefined, keyObj !== {} であるため
myMap.get(function() {}) // undefined, keyFunc !== function () {} であるため

Map のキーとしての NaN の 使用

NaN もまたキーとして使うことができます。すべての NaN は自身と等しくない(NaN !== NaN は真)にもかかわらず、以下の例は動作します。これは 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"

for..of を使用する Map の反復処理

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

forEach()Maps を反復処理

Map は forEach() メソッドを使用して反復できます:

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

Array オブジェクトとの関係

var kvArray = [["キー1", "値1"], ["キー2", "値2"]];

// 通常の Map コンストラクタを使って、キー・値の 2 次元配列をマップに変換する
var myMap = new Map(kvArray);

myMap.get("キー1"); // "値1" を返す

// 展開演算子を使って、マップをキー・値の 2 次元配列に変換する
alert(uneval([...myMap])); // kvArray とまったく同じ Array を表示する

// あるいは展開演算子をキーまたは値のイテレータに使って、キーまたは値のみの配列を得る
alert(uneval([...myMap.keys()])); // Will show ["key1", "key2"]

標準仕様

仕様書 策定状況 コメント
ECMAScript 2015 (6th Edition, ECMA-262)
Map の定義
標準 初期定義。
ECMAScript 2017 Draft (ECMA-262)
Map の定義
ドラフト  

ブラウザ互換性

機能 Chrome Firefox (Gecko) Internet Explorer Opera Safari
基本サポート

38 [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 未サポート 7.1
Map.keys(), Map.values(), Map.entries() 37 [1]
38
20 (20) 未サポート 未サポート 7.1
Map.forEach() 36 [1]
38
25 (25) 11 未サポート 7.1
-0 と 0 のキー等価性 34
38
29 (29) 未サポート 25 未サポート
Constructor argument: new Map(null) (有) 37 (37) ? ? ?
Monkey-patched set() in Constructor (有) 37 (37) ? ? ?
Map[@@species] ? 41 (41) ? ? ?
Map() without new throws ? 42 (42) ? ? ?
機能 Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
基本サポート 未サポート 38 [1] 13.0 (13) 未サポート 未サポート 8
コンストラクタ引数:new Map(iterable) 未サポート 38 13.0 (13) 未サポート 未サポート 未サポート
反復処理可能 未サポート 未サポート 17.0 (17) 未サポート 未サポート 8
Map.clear() 未サポート 31
38
19.0 (19) 未サポート 未サポート 8
Map.keys(), Map.values(), Map.entries() 未サポート 37
38
20.0 (20) 未サポート 未サポート 8
Map.forEach() 未サポート 36
38
25.0 (25) 未サポート 未サポート 8
-0 と 0 のキー等価性 未サポート 34
38
29.0 (29) 未サポート 未サポート 未サポート
Constructor argument: new Map(null) ? (有) 37.0 (37) ? ? ?
Monkey-patched set() in Constructor ? (有) 37.0 (37) ? ? ?
Map[@@species] ? ? 41.0 (41) ? ? ?
Map() without new throws ? ? 42.0 (42) ? ? ?

[1] 設定により使用可能です。chrome://flags において「JavaScript の試験運用機能を有効にする」エントリーを有効化します。

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: YuichiNukiyama, PandaNoir, lv7777, Hixhi, ocha
 最終更新者: YuichiNukiyama,