Map オブジェクトはキーと値の組を保持し、キーが最初に挿入された順序を覚えています。キーや値には任意の値 (オブジェクトとプリミティブ値)を使用することができます。
解説
Map オブジェクトは、その要素について挿入順で反復処理を行うことができます。 for...of ループは各反復で [キー, 値] の配列を返します。
キーの等価性
- キーの等価性は
sameValueZeroアルゴリズムに基づきます。 NaNはNaNと同じとみなされ (NaN !== NaNであっても)、他の値はすべて===演算子の意味に従って等価性が考慮されます。- 現在の ECMAScript 仕様書では、
-0と+0は等しいと考えられています。但し、以前の草稿ではそのようになっていませんでした。詳細は "Value equality for -0 and 0" をブラウザーの互換性一覧で確認してください。
Object と Map の比較
Object と Map は似ています。 — どちらもキーを値に設定したり、それらの値を受け取ったり、キーを削除したり、キーに何かが格納されているかどうかを判定したりすることができます。この意味で (そして他の内蔵オブジェクトがなかったため)、従来 Object は Map として使われてきました。
しかし、いくつかの場面で Map の方が勝るような重要な違いがあります。
| Map | Object | |
|---|---|---|
| 思いがけないキー | Map は既定では何もキーを持っていません。明示的に設定したものだけを含みます。 |
メモ: ES5 では、 |
| キーの型 | Map のキーはあらゆる値がなることができます (関数、オブジェクト、あらゆるプリミティブなど)。 |
Object のキーは String または Symbol でなければなりません。 |
| キーの順序 |
|
メモ: ECMAScript 2015 以降、オブジェクトは文字列と |
| 大きさ | Map の中の項目数は、 size プロパティで簡単に得ることができます。 property. |
Object の中の項目数は、手動で数える必要があります。 |
| 反復処理 | Map は iterable ですので、直接反復処理を行うことができます。 |
Object では反復処理を行うのに、いくつかの形でキーの一覧を取得して、そのうえで反復処理を行う必要があります。 |
| 性能 |
キーと値の組を頻繁に追加したり削除したりすることが求められるシナリオでは、性能がより良くなります。 |
キーと値の組を頻繁に追加したり削除したりすることに最適化されていません。 |
コンストラクター
Map()- 新しい
Mapオブジェクトを生成します。
プロパティ
Map.lengthlengthプロパティの値は0です。
Mapにいくつの項目があるかを数えるには、Map.prototype.sizeを使用してください。get Map[@@species]- 派生クラスを生成するためのコンストラクター関数です。
Map.prototypeMapコンストラクターのプロトタイプを表します。すべてのMapオブジェクトに追加のプロパティを定義できます。
Map インスタンス
すべての Map インスタンスは Map.prototype を継承しています。
プロパティ
Map.prototype.constructor- インスタンスのプロトタイプを生成した関数を返します。これは既定では
Map関数です。 Map.prototype.sizeMapオブジェクトの中のキーと値の組の数を返します。
メソッド
Map.prototype.clear()Mapオブジェクトからすべてのキーと値の組を削除します。Map.prototype.delete(key)Mapオブジェクトに要素が存在し、削除された場合はtrueを返します、要素が存在しなければfalseを返します。その後ではMap.prototype.has(key)がfalseを返すようになります。Map.prototype.entries()Mapオブジェクト内の要素に対して挿入順にすべての要素の[key, value]の配列を含む、新しいIteratorオブジェクトを返します。Map.prototype.forEach(callbackFn[, thisArg])callbackFnを、Mapオブジェクトに存在するそれぞれのキーと値の組に対して1回ずつ、挿入順に呼び出します。thisArg引数がforEachに与えられた場合は、それぞれのコールバックでこれをthisの値として使用します。Map.prototype.get(key)keyで指定されたキーに結び付けられた値を返します。存在しない場合はundefinedを返します。Map.prototype.has(key)keyで指定されたキーに結び付けられた要素がMapオブジェクト内に存在するかどうかを示す boolean を返します。Map.prototype.keys()- 新しい
Iteratorオブジェクトを返し、これにはMapオブジェクト内の各要素のキーが挿入順で含まれます。 Map.prototype.set(key, value)Mapオブジェクト内のkeyで指定されたキーの値をvalueに設定します。そのMapオブジェクトを返します。Map.prototype.values()- 新しい
Iteratorオブジェクトを返し、これにはMapオブジェクト内の各要素の値が挿入順で含まれます。 Map.prototype[@@iterator]()- 新しい
Iteratorオブジェクトを返し、これにはMapオブジェクト内の各要素の[key, value] の配列が挿入順で含まれます。
例
Map オブジェクトの使用
let myMap = new Map()
let keyString = '文字列'
let keyObj = {}
let 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 () {} であるため
NaN の Map のキーとしての使用
NaN もまたキーとして使うことができます。すべての NaN は自身と等しくない (NaN !== NaN は真) にもかかわらず、以下の例は動作します。これは NaN が互いに区別できないためです。
let myMap = new Map()
myMap.set(NaN, 'not a number')
myMap.get(NaN)
// "not a number"
let otherNaN = Number('foo')
myMap.get(otherNaN)
// "not a number"
for..of を使用した Map の反復処理
Map は for..of ループを使用して反復処理を行うことができます。
let myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
for (let [key, value] of myMap) {
console.log(key + ' = ' + value)
}
// 0 = zero
// 1 = one
for (let key of myMap.keys()) {
console.log(key)
}
// 0
// 1
for (let value of myMap.values()) {
console.log(value)
}
// zero
// one
for (let [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)
})
// 0 = zero
// 1 = one
Array オブジェクトとの関係
let kvArray = [["キー1", "値1"], ["キー2", "値2"]];
// 通常の Map コンストラクターを使って、キー・値の 2 次元配列をマップに変換する
let myMap = new Map(kvArray)
myMap.get("キー1") // "値1" を返す
// 展開演算子を使って、マップをキー・値の 2 次元配列に変換する
console.log(Array.from(myMap)) // kvArray とまったく同じ Array を表示する
// あるいは展開演算子をキーまたは値のイテレーターに使って、キーまたは値のみの配列を得る
console.log([...myMap])
// または keys() や values() のイテレーターを使用して配列に変換する
console.log(Array.from(myMap.keys())) // ["key1", "key2"] が出力される
Map の複製と混合
Array のように、 Map は複製することができます。
let original = new Map([ [1, 'one'] ]) let clone = new Map(original) console.log(clone.get(1)) // one console.log(original === clone) // false (useful for shallow comparison)
重要: データ自身は複製されないことに注意しておいてください。
Map はキーの固有性を保持しながら混合可能です。
let first = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]) let second = new Map([ [1, 'uno'], [2, 'dos'] ]) // 2つのマップを混合します。重複するキーは後勝ちになります。 // スプレッド演算子は基本的に Map を Array に変換します。 let merged = new Map([...first, ...second]) console.log(merged.get(1)) // uno console.log(merged.get(2)) // dos console.log(merged.get(3)) // three
Map は Array と混合することもできます。
let first = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]) let second = new Map([ [1, 'uno'], [2, 'dos'] ]) // マップと配列を混合します。重複するキーは後勝ちになります。 let 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
使用上のメモ
ご注意ください。 Map オブジェクトに対するオブジェクトプロパティをの設定は正しく動作しますが、考えられる混乱を引き起こすことがあります。
従って、これは一応動作します・・・
let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'
console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
・・・しかし、期待通りには動作しません。
wrongMap.has('bla') // false
wrongMap.delete('bla') // false
console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
そして、正しい使い方との違いはわずかです。
let myMap = new Map()
myMap.set('bla','blaa')
myMap.set('bla2','blaa2')
console.log(myMap) // Map { 'bla' => 'blaa', 'bla2' => 'blaa2' }
myMap.has('bla') // true
myMap.delete('bla') // true
console.log(myMap) // Map { 'bla2' => 'blaa2' }
仕様書
| 仕様書 |
|---|
| ECMAScript (ECMA-262) Map の定義 |
ブラウザーの互換性
| デスクトップ | モバイル | サーバー | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Map | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 13 | IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 14 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
Map() constructor | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 13 | IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 14 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 あり |
clear | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 19 | IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 19 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
delete | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 13 | IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 14 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
entries | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 20 | IE 未対応 なし | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 20 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
forEach | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 25 | IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 25 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
get | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 13 | IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 14 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 あり |
has | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 13 | IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 14 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 あり |
| Key equality for -0 and 0 | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 29 | IE 未対応 なし | Opera 完全対応 25 | Safari 完全対応 9 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 29 | Opera Android 完全対応 25 | Safari iOS 完全対応 9 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 4.0.0 |
keys | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 20 | IE 未対応 なし | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 20 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
set | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 13 | IE
部分対応
11
| Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 14 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 あり |
size | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox
完全対応
19
| IE 完全対応 11 | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android
完全対応
19
| Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
values | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 20 | IE 未対応 なし | Opera 完全対応 25 | Safari 完全対応 8 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 20 | Opera Android 完全対応 25 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
@@iterator | Chrome 完全対応 43 | Edge 完全対応 12 | Firefox
完全対応
36
| IE 未対応 なし | Opera 完全対応 30 | Safari 完全対応 10 | WebView Android 完全対応 43 | Chrome Android 完全対応 43 | Firefox Android
完全対応
36
| Opera Android 完全対応 30 | Safari iOS 完全対応 10 | Samsung Internet Android 完全対応 4.0 | nodejs 完全対応 0.12 |
@@species | Chrome 完全対応 51 | Edge 完全対応 13 | Firefox 完全対応 41 | IE 未対応 なし | Opera 完全対応 38 | Safari 完全対応 10 | WebView Android 完全対応 51 | Chrome Android 完全対応 51 | Firefox Android 完全対応 41 | Opera Android 完全対応 41 | Safari iOS 完全対応 10 | Samsung Internet Android 完全対応 5.0 | nodejs
完全対応
6.5.0
|
@@toStringTag | Chrome 完全対応 44 | Edge 完全対応 79 | Firefox 完全対応 51 | IE 未対応 なし | Opera 未対応 なし | Safari 未対応 なし | WebView Android 完全対応 44 | Chrome Android 完全対応 44 | Firefox Android 完全対応 51 | Opera Android 未対応 なし | Safari iOS 未対応 なし | Samsung Internet Android 完全対応 4.0 | nodejs 未対応 なし |
凡例
- 完全対応
- 完全対応
- 部分対応
- 部分対応
- 未対応
- 未対応
- 実装ノートを参照してください。
- 実装ノートを参照してください。
- ユーザーが明示的にこの機能を有効にしなければなりません。
- ユーザーが明示的にこの機能を有効にしなければなりません。
- 非標準の名前を使用しています。
- 非標準の名前を使用しています。