--- title: Map slug: Web/JavaScript/Reference/Global_Objects/Map tags: - Class - ECMAScript 2015 - JavaScript - Map - Reference translation_of: Web/JavaScript/Reference/Global_Objects/Map ---
Map
オブジェクトはキーと値のペアを保持し、キーが最初に挿入された順序を覚えています。キーや値には任意の値 (オブジェクトと{{glossary("Primitive", "プリミティブ値")}})を使用することができます。
Map
オブジェクトは、その要素について挿入順で反復処理を行うことができます。 {{jsxref("Statements/for...of", "for...of")}} ループは各反復で [キー, 値]
の配列を返します。
sameValueZero
アルゴリズムに基づきます。NaN
と同じとみなされ (NaN !== NaN
であっても)、他の値はすべて ===
演算子の意味に従って等価性が考慮されます。-0
と +0
は等しいと考えられています。但し、以前の草稿ではそのようになっていませんでした。詳細は "Value equality for -0 and 0" をブラウザーの互換性一覧で確認してください。{{jsxref("Object")}} と Map
は似ています。 — どちらもキーを値に設定したり、それらの値を受け取ったり、キーを削除したり、キーに何かが格納されているかどうかを判定したりすることができます。この意味で (そして他の内蔵オブジェクトがなかったため)、従来 Object
は Map
として使われてきました。
しかし、いくつかの場面で Map
の方が勝るような重要な違いがあります。
Map | Object | |
---|---|---|
思いがけないキー | Map は既定では何もキーを持っていません。明示的に設定したものだけを含みます。 |
注: ES5 では、 {{jsxref("Object.create", "Object.create(null)")}} を使用すると回避できますが、これはめったに行われていません。 |
キーの型 | Map のキーはあらゆる値がなることができます (関数、オブジェクト、あらゆるプリミティブなど)。 |
Object のキーは {{jsxref("String")}} または {{jsxref("Symbol")}} でなければなりません。 |
キーの順序 |
|
通常の この順序は ECMAScript 2015 で初めて自身のプロパティに対してのみ定義されましたが、 ECMAScript 2020 では継承されたプロパティに対しても同様に順序が定義されています。 OrdinaryOwnPropertyKeys と EnumerateObjectProperties の抽象指定操作を参照してください。しかし、オブジェクトのプロパティがすべて反復処理される単一の単一のメカニズムはないことに注意してください。 ({{jsxref("Statements/for...in", "for-in")}} は列挙可能な文字列キーのプロパティのみを含む、 {{jsxref("Object.keys")}} は自分自身の列挙可能な文字列キーのプロパティのみを含む、 {{jsxref("Object.getOwnPropertyNames")}} は列挙不可能な場合でも自分自身の文字列キーのプロパティを含む、 {{jsxref("Object.getOwnPropertySymbols")}} は、 |
大きさ |
Map の中の項目数は、 {{jsxref("Map.prototype.size", "size")}} プロパティで簡単に得ることができます。 property. |
Object の中の項目数は、手動で数える必要があります。 |
反復処理 | Map は iterable ですので、直接反復処理を行うことができます。 |
Object では反復処理を行うのに、いくつかの形でキーの一覧を取得して、そのうえで反復処理を行う必要があります。 |
性能 |
キーと値の組を頻繁に追加したり削除したりすることが求められるシナリオでは、性能がより良くなります。 |
キーと値の組を頻繁に追加したり削除したりすることに最適化されていません。 |
Map オブジェクトに対してオブジェクトプロパティを設定すると正しく動作しますが、混乱を催すことが考えられます。
たとえば、次の例は一応動作するように見えます。
let wrongMap = new Map() wrongMap['bla'] = 'blaa' wrongMap['bla2'] = 'blaaa2' console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
しかし、このようにプロパティを設定すると、 Map データ構造に符合しません。一般的なオブジェクトの機能を使用します。 'bla' の値はクエリを行うための Map に格納されません。データにその他の操作を行うと失敗します。
wrongMap.has('bla') // false wrongMap.delete('bla') // false console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
Map にデータを格納する正しい方法は、 set(key, value)
メソッドを使用する方法です。
let contacts = new Map() contacts.set('Jessie', {phone: "213-555-1234", address: "123 N 1st Ave"}) contacts.has('Jessie') // true contacts.get('Hilary') // undefined contacts.set('Hilary', {phone: "617-555-4321", address: "321 S 2nd St"}) contacts.get('Jessie') // {phone: "213-555-1234", address: "123 N 1st Ave"} contacts.delete('Raymond') // false contacts.delete('Jessie') // true console.log(contacts.size) // 1
Map
オブジェクトを生成します。Map
オブジェクトの中のキーと値の組の数を返します。Map
オブジェクトからすべてのキーと値の組を削除します。Map
オブジェクトに要素が存在し、削除された場合は true
を返します、要素が存在しなければ false
を返します。その後では Map.prototype.has(key)
が false
を返すようになります。key
で指定されたキーに結び付けられた値を返します。存在しない場合は undefined
を返します。key
で指定されたキーに結び付けられた要素が Map
オブジェクト内に存在するかどうかを示す boolean を返します。Map
オブジェクト内の key
で指定されたキーの値を value
に設定します。その Map
オブジェクトを返します。Map
オブジェクト内の各要素の [key, value] の配列
が挿入順で含まれます。Map
オブジェクト内の各要素のキーが挿入順で含まれます。Map
オブジェクト内の各要素の値が挿入順で含まれます。Map
オブジェクト内の要素に対して挿入順にすべての要素の [key, value]
の配列を含む、新しいイテレーターオブジェクトを返します。callbackFn
を、 Map
オブジェクトに存在するそれぞれのキーと値の組に対して1回ずつ、挿入順に呼び出します。 thisArg
引数が forEach
に与えられた場合は、それぞれのコールバックでこれを this
の値として使用します。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 () {} であるため
{{jsxref("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"
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
Map は {{jsxref("Map.prototype.forEach", "forEach()")}} メソッドを使用して反復できます。
myMap.forEach(function(value, key) { console.log(key + ' = ' + value) }) // 0 = zero // 1 = one
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"] が出力される
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
仕様書 |
---|
{{SpecName('ESDraft', '#sec-map-objects', 'Map')}} |
{{Compat("javascript.builtins.Map")}}